Мне нужно перевести хэш-функцию с JavaScript на Python.
Функция выглядит следующим образом:
function getIndex(string) {
var length = 27;
string = string.toLowerCase();
var hash = 0;
for (var i = 0; i < string.length; i++) {
hash = string.charCodeAt(i) + (hash << 6) + (hash << 16) - hash;
}
var index = Math.abs(hash % length);
return index;
}
console.log(getIndex(window.prompt("Enter a string to hash")));
Эта функция объективно верна ™. Это само совершенство. Я не могу изменить это, я просто должен воссоздать это. Что бы он ни выводил, мой скрипт на Python также должен выводить.
Однако - у меня есть пара проблем, и я думаю, что все это связано с тем, как два языка обрабатывают целые числа со знаком.
Битовые операторы JS обрабатывают свои операнды как последовательность из 32 битов. Python, однако, не имеет концепции ограничения битов и просто продолжает действовать как абсолютный безумный. Я думаю, что это одно существенное различие между двумя языками.
Я могу ограничить длину hash
в Python, маскируя ее до 32 битов с помощью hash & 0xFFFFFFFF
.
Я также могу отрицать hash
, если он выше 0x7FFFFFFF
с hash = hash ^ 0xFFFFFFFF
(или hash = ~hash
- они оба, кажется, делают одно и то же). Я считаю, что это имитирует отрицательные числа.
Я применяю оба эти ограничения к хешу с помощью функции t
.
Вот мой код на Python:
def nickColor(string):
length = 27
def t(x):
x = x & 0xFFFFFFFF
if x > 0x7FFFFFFF:
x = x ^ 0xFFFFFFFF
return x
string = string.lower()
hash = t(0)
for letter in string:
hash = t(hash)
hash = t(t(ord(letter)) + t(hash << 6) + t(hash << 16) - t(hash))
index = hash % length
return index
Кажется, он работает до тех пор, пока хэш не должен стать отрицательным, после чего два сценария расходятся. Это обычно происходит около 4 букв в строке.
Я предполагаю, что моя проблема заключается в воссоздании отрицательных чисел JS в Python. Как я могу сказать пока этой проблеме?