我创建了一个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 中实现它?
正确的输出是 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))