У меня есть миллион случайно сгенерированных уникальных идентификаторов.
If I do:
result = int(hash(id + 'some_salt')) % 1000
Тогда это, по-видимому, приводит к равномерному распределению идентификаторов до некоторого целого числа от 0 до 999, при этом каждому целому числу соответствует примерно 1000 идентификаторов.
Если я теперь добавлю немного соли к этому и снова возьму хэш:
x = int(hash(id)) % 1000
result = int(hash(str(x) + 'some_salt') % 1000)
Тогда полученное распределение будет совершенно неравномерным. Для каждого идентификатора результат, конечно, находится в диапазоне [0,999], но некоторые целые числа в этом диапазоне имеют нулевые идентификаторы, в то время как другие имеют несколько тысяч.
Почему это приводит к очень неравномерному распределению значений?
Как я могу настроить это, чтобы привести к равномерному распределению целых чисел в диапазоне [0,999] для моего миллиона идентификаторов и любой заданной соли? Я хочу сохранить промежуточный шаг по уменьшению потенциально очень большого входного пространства до гораздо меньшего пространства (например, размером 1000).
Я использую хеширование SHA-256.
Вот некоторый код Python, который демонстрирует очень неравномерные результаты:
import numpy as np
import hashlib
OUTPUT_RANGE_SIZE = 1000
unique_ids = xrange(1000000) # sequential here, but could be any kind of unique ids
frequencies = np.zeros(OUTPUT_RANGE_SIZE, dtype='int')
for idx in xrange(len(unique_ids)):
id = unique_ids[idx]
hash_mod = int(hashlib.sha256(str(id)).hexdigest(), 16) % 1000
result = int(hashlib.sha256(str(hash_mod) + 'some_salt').hexdigest(), 16) % OUTPUT_RANGE_SIZE
frequencies[result] = frequencies[result] + 1
print frequencies