Shift JIS编码中的非法序列0x82 0x51

编程语言 2026-07-11

我手头有字节序列 0x83 89 83 93 83 4F 83 8A 83 62 83 54 81 5B 82 51,需要判断它是纯ASCII还是某种Shift JIS。它来自一张世嘉Mega Drive的镜像,其中游戏描述是按目标市场(日本、欧洲、美国等)来定位的。

Shift JIS验证……

于是我检查字节是否完全符合Shift JIS的模式:

  • 0x000x1F 以及 0x7F 的字节无效。
  • 字节 0x800xA0 以及从 0xFD0xFF 在扩展版本中是有效的。
  • 0x810x9F 以及从 0xE00xEF(在扩展版本中从 0xF00xFC 也是)是一个有效的起始字节,但是:
  • 如果它们是奇数,随后的字节必须在 0x400x7E 之间,或在 0x800x9E 之间。
  • 如果它们是偶数,随后的字节必须在 0x9F0xFC 之间。

…对照输入

前14个字节按照 Shift JIS字节映射 的规定可以正常工作:

  • 0x83 是一个奇数起始字节,后面的字节应在 0x400x9E 之间。
  • 接下来的5 对字节遵循相同模式。
  • 0x81 再次是一个奇数起始字节,后面的字节应在 0x400x9E 之间。
  • 但最后一对违反了编码:0x82 是一个偶数起始字节,因此其后面的字节必须在 0x9F0xFC 之间。但事实并非如此。

把前14个字节翻译成 ラングリッサー,这是可以的。

然而

如果我在WinAPI中使用 MultiByteToWideChar( 932, 0, ... ),其中Code Page 932是 Shift JIS的一个扩展(参见 Code Page 932的布局),并提交全部16个字节,我竟然得到的翻译结果是 ラングリッサー2——从文本上下文来看这也是一个有效的文本(国际版本的游戏标题是 Langrisser II)。

问题

为什么按照Shift JIS,字节序列 0x82 51 是无效的?按 CP 932的布局 应该甚至也是无效的。我到底漏看了什么?

解决方案

Windows 932

关于Code Page 932布局的维基百科条目具有误导性。根据Unicode 1998年的映射,序列 0x82 51 是合法的:

#        Column #1 is the cp932 code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
0x8251  0xFF12  #FULLWIDTH DIGIT TWO

0x82 作为字符的首字节时,后面的字节可以是

  • 0x4F0x58,或
  • 0x600x79,或
  • 0x810x9A,或
  • 0x9F0xF1——按照布局示意图,这个范围应该是唯一有效的。

Shift JIS 0208

然而,即使是 Unicode对 Shift JIS 0208的映射 也将两字节都视为有效:

#        Column #1 is the shift-JIS code (in hex)
#        Column #2 is the JIS X 0208 code (in hex as 0xXXXX)
#        Column #3 is the Unicode (in hex as 0xXXXX)
#        Column #4 the Unicode name (follows a comment sign, '#')
0x8251  0x2332  0xFF12  # FULLWIDTH DIGIT TWO

其实我确实应该查阅实际的文献,看看JIS 0208支持的字节组合要比 [Wikipedia条目中的布局示意] 所暗示的多得多。

结论

我的验证显然是错误的,因为它允许的字节组合太少了。我无法核实这张电子游戏镜像是否按1990年代的原样未被修改,或者其元数据是否使用更新的软件编写,但归根结底这也无关紧要,因为该组合在当时甚至就是有效的 [JIS X 0208]。我很确定世嘉的游戏没有使用Windows,因此我不需要把 932 视为我需要预期的编码。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章