将十六进制字节数组解码为特定代码页会在之后编码时带来错误结果

问题描述

我创建了一个简单的应用程序,如下所示:

    String stringValue = new String(new byte[] { 0x00,0x00,0x25 },"273");
    byte[] valueEncoded = Arrays.copyOfRange(stringValue.getBytes("273"),4);
    int finalResult = ByteBuffer.wrap(valueEncoded).getInt();
    
    System.out.println("Result: "+finalResult);

我希望结果是 37,结果是 21。怎么会呢?我错过了什么吗?或者我的方法不是它应该的方式,因此会弹出这个错误

我尝试了许多其他数字,但似乎一切正常... 如您所见,我使用的是代码页 273 (IBM)。

解决方法

在我看来,换行符 0x25 被映射到换行符 0x15。

我假设它是这样的:

字节到字符串:EBCDIC 0x25 -> UTF-16 0x000A

字符串到字节:UTF-16 0x000A -> EBCDIC 0x15。

为什么这是首选,我猜不出来。好吧,实际上我可以猜到(但这只是猜测)。 0x000A 是许多系统上的标准行终止符,但它通常输出为“移动到下一行的开头”。转换为 IBM 273 是“可能的”,因为文本的目标是在使用该代码页的设备上输出,而且这些设备可能需要 NL 而不是 LF 来开始新行。


假设得到验证:

 class D {
   public static void main(String... a) throws Exception {
       String lf = "\n";
       byte[] b = lf.getBytes("273");
       System.out.println((int)b[0]);
   }
}

输出为 21。