Вот в чем проблема - ваш диапазон чисел имеет только 3,6x10 ^ 9 возможных значений, где в качестве образца уникальная строка (которая выглядит как шестнадцатеричное целое с 36 цифрами) имеет 16 ^ 32 возможных значений (т.е. много Больше).Таким образом, при отображении вашей строки в ваш целочисленный диапазон будут возникать коллизии .
Сама функция отображения может быть довольно простой, я бы сделал что-то подобное, как показано ниже (также рассмотрим использование только частивходной строки для целочисленного преобразования, например, первые семь цифр, если производительность становится критической):
def my_hash(str, min, max)
range = (max - min).abs
(str.to_i(16) % range) + min
end
my_hash(did, min_cid, max_cid) # => 2461595789
[Редактировать] Если вы используете Ruby 1.8 и ваш настроенный диапазон может бытьпредставленный как Fixnum
, просто используйте hash
значение объекта входной строки вместо анализа его как большого целого числа.Обратите внимание, что эта стратегия может быть небезопасной в Ruby 1.9 (согласно комментарию @DataWraith), поскольку значения хеш-объекта могут быть рандомизированы между вызовами интерпретатора, поэтому вы не получите тот же номер хеш-кода для той же строки ввода при перезапуске приложения:
def hash_range(obj, min, max)
(obj.hash % (max-min).abs) + [min, max].min
end
hash_range(did, min_cid, max_cid) # => 3886226395
И, конечно, вам придется решить, что делать с коллизиями.Скорее всего, вам придется сохранить набор входных строк, которые соответствуют одному и тому же значению, и решить, как разрешить конфликты, если вы ищите по отображенному значению.