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

时间:2014-11-13 21:30:58

标签: java php utf-8 sha1

我创建了一个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中实现它?

1 个答案:

答案 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))