我创建了一个Sha1函数,它在大多数情况下与PHP的sha1函数一样工作,并提供相同的输出。但是当出现UTF-8字符时,它们会有所不同。例如,使用字符串“hj6”,在PHP中我得到“7f9d591232c5fde9f757c4d8472921517991dc3c”,而在我的Java函数中,我得到“c963b7df20488e9ef50c1a309c1fa747ab5d8822”。这是Java函数:
https://github.com/Razican/Java-Utils/blob/master/src/razican/utils/StringUtils.java#L115
哪一个是正确的?如何在Java中实现它?
答案 0 :(得分:1)
正确的输出是 7f9d591232c5fde9f757c4d8472921517991dc3c 。你丢弃了一个字节:
final MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(str.getBytes("UTF-8"), 0, str.length());
sha1hash = md.digest();
上面的代码假定UTF-16字符串的长度等于UTF-8编码字节数组的长度。如果UTF-8表格比UTF-16表格长,则摘要将不正确。
codepoint glyph escaped UTF-8 info
=======================================================================
U+0068 h \u0068 68, BASIC_LATIN, LOWERCASE_LETTER
U+006a j \u006a 6a, BASIC_LATIN, LOWERCASE_LETTER
U+0036 6 \u0036 36, BASIC_LATIN, DECIMAL_DIGIT_NUMBER
U+00ac ¬ \u00ac c2,ac, LATIN_1_SUPPLEMENT, MATH_SYMBOL
使用数组的长度:
byte[] utf8 = str.getBytes(StandardCharsets.UTF_8);
md.update(utf8, 0, utf8.length);
您也可以使用md.update(str.getBytes(StandardCharsets.UTF_8))