我有计算字符串SHA-256哈希的代码,并且注意到我从Android和Oracle Java 7获得了不同的哈希以获得相同的字符串。我的散列码转换成String
与byte[]
:使用Android和Oracle进行字符串字符编码Java
byte[] data = stringData.getBytes("UTF-16");
使用UTF-16编码,我从甲骨文的Java和Android的Java不同的结果。这是我散列字符串:
// Test Code:
String toHash = "testdata";
System.out.println("Hash: " +DataHash.getHashString(toHash));
并获得论文哈希使用UTF-16:
Hash: a1112a0363a59097a701e38398e1fdfef3049358aee81b77ecaad2924a426bc5 [Oracle Java 7]
Hash: 811b723aee07c7a52456fc57a5683e73649075a373d341f7257bf73575111ba3 [Android 2.2]
然而,UTF-8,我得到了相同的散列两者的JRE:
Hash: 810ff2fb242a5dee4220f2cb0e6a519891fb67f2f828a6cab4ef8894633b1f50 [Oracle Java 7]
Hash: 810ff2fb242a5dee4220f2cb0e6a519891fb67f2f828a6cab4ef8894633b1f50 [Android 2.2]
是否存在某种类型的endian-ness问题,这会导致不同平台上的不同结果?我应该如何真正准备一个字符串以独立于平台的方式进行散列?
编辑: 哎呀,答案是相当明显的,一旦你读了关于UTF-16多一点。有两种版本的UTF-16(大端和小端)。你只需要指定getBytes()应该使用哪个版本,并且散列值是相同的。挑一个:
- UTF-16LE
- UTF-16BE
啊,有趣。它看起来像Android(2。2至少)正在进行小端转换: Oracle Java 7: “UTF-16:[-2,-1,0,116,0,101,0,115,0,116,0,100 ,0,97,0,116,0,97]' Android Java 2.2: 'UTF-16:[-1,-2,116,0,101,0,115,0,116,0,100 ,0,97,0,116,0,97,0]' –
@TajMorton'-1,-2,116,0..'是Little Endian,带有LE BOM。这是从Android?无论如何,它显然与Android文档相矛盾。 – Esailija
对不起,我的格式化已被破坏,并在我准备好之前意外发布。 Oracle Java 7为'[-2,-1,0,116]'提供了“UTF-16”,而Android 2.2提供了'[-2,-1,116,0]'。所以是的,它看起来像是用LE BOM生产LE。 –