EBCDIC (Cp1047) junit 0D25

EBCDIC (Cp1047) junit 0D25

我正在处理一些以 EBCDIC 编码的数据,我需要替换一些值。

其中一个值是十六进制字节 0D 25,必须变为 40 40

我的理解是EBCDIC字符如下:

当在具有此编码的 String 中找到此对时,必须用两个空格替换(十六进制 40,两次)。另见 wikipedia EDCDIC character table.

我理解 0D(回车 return)等同于 \r25(换行)是(应该是?)\n在 UTF-16 中。因此:

assertThat(minimalExample("\r\n")).isEqualTo(" ");

应该通过,给定如下定义的最小方法

String minimalExample(String raw) throws Exception {
    byte[] bytes = raw.getBytes("Cp1047");
    if (bytes[0] == 0x0d && bytes[1] == 0x25) {
        bytes[0] = 0x40;
        bytes[1] = 0x40;
    }
    return new String(bytes, "Cp1047");
}

我最终得到的是

Expecting:
 <"
">
to be equal to:
 <" ">
but was not.

因为给定字符串的第二个十六进制值是 15(不是我认为的 25)。

似乎 25 在 UTF-16 中表示为 \u0085

这是正确的吗?

EBCDIC 换行符有一个单独的 Unicode 代码点 NEL = U+0085。例如 BufferedReader.readLine 也将其作为行分隔符。

EBCDIC LF 0X25 不是 \n,而是 \u0085\n 总是 \u000a。 UTF-16.

应该在 byte[] 上进行单元测试,并且应该检查代码读取行不会在 EBCDIC 中的字节 0d 25 上读取额外的空行。

在正则表达式中,您可以使用 "\R" 作为其他行分隔符:

s = s.replaceAll("\R", ".");