我有計算字符串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。 –