不支持的字符的Groovy字符编码结果不匹配

时间:2018-03-29 05:55:26

标签: java php groovy utf-8 character-encoding

到目前为止,这是我的分析和障碍,假设下面的字符,基本上由“UTF-8”字符集支持,并且不支持“EUC-JP”。 “ - ” 对于php,有一个方法“var_dump(input_string)”将任何字符串转换为字节数组,编码为“EUC-JP”,在这种情况下,它返回,

[161, 189, 10] //Note: [3]=>int(10) for Line Feed.

类似地,当我使用编码“UTF-8”生成字节数组时,在这种情况下它会返回,

[226, 128, 141,10] //Note: [4]=>int(10) for Line Feed.

但是,当我在Groovy中尝试同样的事情时, 它的行为完全不同,对于EUC-JP,字节排列如下,

[-95, -67, 10] //Note: [3]=>int(10) for Line Feed.

对于UTF-8,

[-30, -128, -107, 10] //Note: [4]=>int(10) for Line Feed.

N.B。,我直接从分别用EUC-JP和UTF-8编码的2个不同文本文件中获取数据。所有上述数组的最后一个字节用于LF(换行)。由于字节排列对于这两种语言的相同字符编码是不同的,因此不可能在它们之间匹配生成的散列。

到目前为止,这是代码示例,以php开头,

<?php
$myfile = fopen("euc_jp.txt", "r") or die("Unable to open file!");
$str1 = fread($myfile,filesize("euc_jp.txt"));

echo "Read From File EUC-JP:<br/>";
echo $str1;
$byte_array1 = unpack('C*', $str1);
echo "<br/>Byte Dump of EUC-JP File Content:<br/>";
var_dump($byte_array1);

echo "<br/><br/>";
$myfile2 = fopen("utf_8.txt", "r") or die("Unable to open file!");
$str2 = fread($myfile2,filesize("utf_8.txt"));

echo "<br/><br/>";
echo "Read From File UTF-8:<br/>";
echo $str2;
$byte_array2 = unpack('C*', $str2);
echo "<br/>Byte Dump of EUC-JP File Content:<br/>";
var_dump($byte_array2);


$encodedToEucJp = mb_convert_encoding($str2, "EUC_JP");
echo "<br/><br/>After conversion (UTF-8) to (EUC-JP): <br/>";
echo $encodedToEucJp;

echo "<br/><br/>";

echo "Hash Generation Directly From EUC-JP:<br/>";
print_r(md5($str1));

echo "<br/><br/>";
echo "Hash Generation From UTF-8 File Content After Encoded to EUC-JP:<br/>";
print_r(md5($encodedToEucJp));

fclose($myfile);
fclose($myfile2);
?>

对于Groovy,

println(new File('/var/www/html/euc_jp.txt').getText('EUC-JP').getBytes("EUC-JP"))
println(new File('/var/www/html/utf_8.txt').getText('UTF-8').getBytes("UTF-8"))

这是我的障碍,首先这两种语言的字节表示是不同的,如果它不是Groovy和Java8的限制,我如何产生由php生成的相同字节排列,其次,什么是本机php函数的等效代码,b_convert_encoding()。所以,我能够转换任何字符串编码,其中可能有一些字符不受编码机制的支持。

1 个答案:

答案 0 :(得分:1)

Java和Groovy字节是two's complement 签名值,即一个字节的值介于-128+127之间。

要计算同一个字节的相应无符号值,请将256添加到负值,例如-95 + 256 = 161

所以,你看到的是相同的字节。只是PHP将值打印为 unsigned ,而Groovy将值打印为 signed 。它们在一个字节中仍然是相同的8位。

Unsigned             Signed                 Hex
161, 189, 10      == -95, -67, 10        == A1, BD, 0A
226, 128, 141, 10 == -30, -128, -115, 10 == E2, 80, 8D, 0A
226, 128, 149, 10 == -30, -128, -107, 10 == E2, 80, 95, 0A

E2 80 8DUnicode Character 'ZERO WIDTH JOINER' (U+200D)的UTF-8。

E2 80 95Unicode Character 'HORIZONTAL BAR' (U+2015)的UTF-8。

如果要将字节数组的值打印为可读文本,我建议您使用2位数HEX打印字节。这样每个字节的长度始终为2个十六进制数。