为什么Python和Java在解码GBK时表现不同

xriantvc  于 2023-05-15  发布在  Java
关注(0)|答案(1)|浏览(179)

这个问题与How to decode bytes in GB18030 correctly有关。
我想解码一个用GBK编码的字节数组,但发现Python和Java有时行为不同。

ch = b'\xA6\xDA'
print(ch.decode('gbk'))

它会引发一个错误:
UnicodeDecodeError:“gbk”编解码器无法解码位置0中的字节0xa6:非法多字节序列
Java可以破解它。

byte[] data = {(byte) 0xA6, (byte) 0xDA};
String s = new String(data, Charset.forName("GBK"));
System.out.println(s);

Python和Java似乎对GBK采用了不同的实现,对吗?

brc7rcf0

brc7rcf01#

看起来Python和Java对GBK采用了不同的实现,对吗?
是的。GBK在某种程度上是一种模糊的编码,因此不同的平台可能会采用不同的实现方式。
至于Python(这里是CPython),GBK到Unicode的Map是在mappings_cn.h中定义的,这是CP936的 * 严格 * 实现,其中一些非中文地区的字符(如0xA6DA)没有定义。
相比之下,Java中的GBK(这里是OpenJDK 17)实际上是一个 * 扩展的 * CP 936,其中包括一些额外的非中文字符,以遵循GB 18030/MS 936。例如,0xA6DAMap到Unicode U+E78E(尽管它是私有用户区域)。

相关问题