android之为什么 Yen (U+00A5) 符号的 Android Shift-JIS 编码会产生 -4,-4

kerrycode 阅读:140 2025-02-15 21:57:57 评论:0

运行以下代码似乎生成了错误的值:

byte[] data = "\u00a5".getBytes("Shift_JIS"); 

它产生 [ -4, -4 ],但我期望 [ 0x5c ]

我尝试了各种替代名称,“Shift-JIS”、“shift_jis”、“cp932”,并且都产生了相同的结果。

当我将结果数据输入 Shift-JIS 解码器时,出现异常:java.nio.charset.UnmappableCharacterException: Length: 2

即解码器配置如下:

Charset charset = Charset.forName("Shift_JIS); 
        CharsetDecoder decoder = charset.newDecoder() 
                .onMalformedInput(CodingErrorAction.REPORT) 
                .onUnmappableCharacter(CodingErrorAction.REPORT); 

但考虑到编码器的输出看起来不对,我的猜测是解码器无关紧要。我的观点是,无论实际字节数如何,编码器都会生成它无法解码的数据。

全宽 Yen (U+FFE5) 编码为 [ -127 (0x81), -113 (0x8F) ],并正确解码。

奇怪的是,如果我尝试解码 [ 92 (0x5C) ] 这是我认为单宽度日元的 Shift-JIS 编码,Android/Java 解码器会生成一个反斜杠,将字符保留为 92。

如果编码器不支持给定的字符,我希望有一个替换字符,例如“?”。但是 -4 (0xFC) 似乎甚至不是有效的 Shift-JIS。它甚至不是 Unicode 替换字符 U+FFFD。 使用以下行我可以看到编码器似乎配置为使用 [-4, -4]:

Charset.forName("Shift_JIS").newEncoder().replacement() 
  • 那么为什么没有在 Shift-JIS 中映射单一宽度的日元?
  • [-4, -4] 是一个合理的编码器替代品吗?
  • 为什么解码器不支持 0x5C 映射到 Yen (U+00A5)?
  • 如果 0x5C 不是正确的编码,那是什么?

请您参考如下方法:

部分答案:当微软为 Windows 创建其东亚代码页时,如日语代码页 932 和韩语代码页 949,他们将字节 0x5C 呈现为货币符号(要么是日元符号或韩元符号),同时在语法上仍充当文件路径中的反斜杠字符(因此日文系统上的文件路径可能看起来像

C:¥Documents¥something.doc 

)。因此这个字节在某种意义上是一个日元符号,但在某种意义上也是一个反斜杠;根据 http://archives.miloush.net/michkap/archive/2005/09/17/469941.html,在日文系统中,根据字体,相同的字节甚至被呈现为这些符号中的不同符号。 .

编码中符号的含义缺乏一致意味着虽然 Shift-JIS 编码器 可以明智地映射 \¥ 到字节 0x5C,试图将 Shift-JIS 编码的字符串映射到一系列 unicode 代码点的解码器 无法知道是否转换字节 0x5C 到反斜杠或日元符号;日本用户过去常常通过他们的字体选择来做出选择(如果他们能够做出的话)。

面对这种无法修复的歧义,所有解码器似乎都选择将0x5C解码为反斜杠。 (至少,Python 会这样做,并且 the WhatWG have a spec that dictates it 。)

关于在 shift_jis 中对日元符号进行编码时,Java/Android 正在做什么的细节,恐怕我不知道。


标签:Android
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号