В службе A у меня есть строка, которая хэшируется следующим образом:
fun String.toHash(): Long {
var hashCode = this.hashCode().toLong()
if (hashCode < 0L) {
hashCode *= -1
}
return hashCode
}
Я хочу воспроизвести этот код в сервисе B, написанном на Golang, чтобы для того же слова я получил точно такой же хэш. Насколько я понимаю из документации Kotlin, примененный хеш возвращает 64-битное целое число. Итак, в Go я делаю это:
func hash(s string) int64 {
h := fnv.New64()
h.Write([]byte(s))
v := h.Sum64()
return int64(v)
}
Но во время модульного тестирования я не получаю такого же значения. Я получил:
func Test_hash(t *testing.T) {
tests := []struct {
input string
output int64
}{
{input: "papafritas", output: 1079370635},
}
for _, test := range tests {
got := hash(test.input)
assert.Equal(t, test.output, got)
}
}
Результат:
7841672725449611742
Я делаю что-то неправильно?
@JimB Большое спасибо! Это был нужный мне импульс и конструктивный ответ.
Java и, следовательно, Kotlin используют другую хеш-функцию, чем Go.
Возможные варианты:
Да, я вижу это. Могу ли я как-нибудь воспроизвести путь «Котлина» в Go? Я действительно не хочу ничего менять на сервисе Kotlin.
Алгоритм хеширования Java/Kotlin не указан в спецификации, не так ли? Так что на него нельзя положиться — он может меняться между реализациями JVM (или даже разными версиями одной и той же JVM). Если вам нужен конкретный алгоритм, я думаю, гораздо безопаснее реализовать его самостоятельно.
@gidds: я не уверен, где java рисует задокументированную строку по сравнению с указанной, но алгоритм задокументирован (но я согласен, что использование стандартизированного хэша имело бы больше смысла)
@JimB А, так это задокументировано! Спасибо за ссылку. (Я не был уверен, отсюда и вопрос :-) Так что было бы безопасно реализовать его повторно. Хотя я предполагаю, что если вам все равно придется реализовать хэш в Go, вероятно, будет понятнее (и проще отлаживать), если вы выберете свой собственный алгоритм и реализуете его на обоих языках.
Если вы не хотите использовать стандартный хэш, вы можете реализовать java-версию самостоятельно: stackoverflow.com/questions/15518418/…