Я создал функцию Sha1, которая работает в большинстве случаев так же, как функция sha1 в PHP, и выдает тот же результат. Но когда появляются символы 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))
Других решений пока нет …