Разница между Murmur3 на C# и Java ⇐ C#
-
Anonymous
Разница между Murmur3 на C# и Java
Проблема: мне нужно переписать проект (на C#), в котором генерация хэшей осуществляется с использованием алгоритма Murmur, следующим образом:
private static ThreadLocal HashProvider => new(() => MurmurHash.Create128()); общедоступная строка GetHash (строковые данные) { var bytes = Encoding.UTF8.GetBytes(данные); вернуть Convert.ToBase64String( HashProvider.Value.ComputeHash(байты) ); } Выглядит довольно стандартно. Проблема в том, что когда я пытаюсь воспроизвести этот фрагмент на Java, на выходе получается совершенно другой хэш.
Код на Java:
import com.google.common.hash.HashCode; импортировать com.google.common.hash.Hashing; импортировать java.nio.charset.StandardCharsets; импортировать java.util.Base64; публичный финальный класс HashUtils { общественная статическая строка getHash (строковые данные) { Хэш HashCode = Hashing.murmur3_128().hashString(data, StandardCharsets.UTF_8); byte[] байты = hash.asBytes(); вернуть Base64.getEncoder().encodeToString(байты); } } Этапы метода:
[*]Преобразовать строку в массив байтов [*]Хеширование байтов с использованием алгоритма Murmur [*]Преобразовать массив байтов обратно в строку
Проблема на втором этапе.
Я пробовал:
[*][x] java.security.MessageDigest на com.google.common.hash.Hashing — не поддерживает Murmur. Доказательство [*][x] com.google.common.hash.Hashing дает другой результат [*][x] org.apache.commons.codec.digest.MurmurHash3 создает другой формат хеш-функции (как массив из двух длинных) [*][x] Было проверено, что версия 3 Murmur используется в C#, а также в Java. [*][x] Мы использовали тот же вариант, что и в C#, в 128 битах. В Wiki сказано, что для 128-битной версии реализации различаются для платформ x86 и x64. Мы попробовали это на одной машине. Но это был Мак. Нет никаких гарантий, что C# и Java будут одинаково работать с архитектурой ARM. [*][x] Мы подумали, что существует разница между тем, как работает кодирование с помощью UTF8 в C# и Java. Но нет. Полученные байты одинаковы.
Результат: невозможно реализовать на Java алгоритм, который генерировал бы полностью идентичный хеш, такой же, как генерируется C#
Проблема: мне нужно переписать проект (на C#), в котором генерация хэшей осуществляется с использованием алгоритма Murmur, следующим образом:
private static ThreadLocal HashProvider => new(() => MurmurHash.Create128()); общедоступная строка GetHash (строковые данные) { var bytes = Encoding.UTF8.GetBytes(данные); вернуть Convert.ToBase64String( HashProvider.Value.ComputeHash(байты) ); } Выглядит довольно стандартно. Проблема в том, что когда я пытаюсь воспроизвести этот фрагмент на Java, на выходе получается совершенно другой хэш.
Код на Java:
import com.google.common.hash.HashCode; импортировать com.google.common.hash.Hashing; импортировать java.nio.charset.StandardCharsets; импортировать java.util.Base64; публичный финальный класс HashUtils { общественная статическая строка getHash (строковые данные) { Хэш HashCode = Hashing.murmur3_128().hashString(data, StandardCharsets.UTF_8); byte[] байты = hash.asBytes(); вернуть Base64.getEncoder().encodeToString(байты); } } Этапы метода:
[*]Преобразовать строку в массив байтов [*]Хеширование байтов с использованием алгоритма Murmur [*]Преобразовать массив байтов обратно в строку
Проблема на втором этапе.
Я пробовал:
[*][x] java.security.MessageDigest на com.google.common.hash.Hashing — не поддерживает Murmur. Доказательство [*][x] com.google.common.hash.Hashing дает другой результат [*][x] org.apache.commons.codec.digest.MurmurHash3 создает другой формат хеш-функции (как массив из двух длинных) [*][x] Было проверено, что версия 3 Murmur используется в C#, а также в Java. [*][x] Мы использовали тот же вариант, что и в C#, в 128 битах. В Wiki сказано, что для 128-битной версии реализации различаются для платформ x86 и x64. Мы попробовали это на одной машине. Но это был Мак. Нет никаких гарантий, что C# и Java будут одинаково работать с архитектурой ARM. [*][x] Мы подумали, что существует разница между тем, как работает кодирование с помощью UTF8 в C# и Java. Но нет. Полученные байты одинаковы.
Результат: невозможно реализовать на Java алгоритм, который генерировал бы полностью идентичный хеш, такой же, как генерируется C#
Мобильная версия