SHA-1 在 UTF-8 Java 中显示不同的输出


SHA-1 shows different output in UTF-8 Java

我创建了一个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))