2014-12-20 4 views
2

Мне нужно создать уникальный хеш, который соответствует ID в базе данных. Должен ли я просто генерировать случайный буквенно-цифровой хеш, который я затем сохраняю в этой конкретной строке в базе данных?Создать уникальный хэш

Прямо сейчас это то, что я делаю, но мне нужно убедиться, что люди не могут найти алгоритм, который создает эти хеши.

params[:slug].to_i(36) 

id.to_s(36) 
+0

Вы можете проверить это один из: http://stackoverflow.com/questions/6338870/how-to-implement-a-short-url-like-urls-in-twitter – Casper

+0

Базы данных преуспеть в генерируя значения UID, поэтому проверьте документацию DBM, чтобы узнать, что он поддерживает. Было бы быстрее позволить DBM сделать это, чем Rails. –

ответ

3

Очень просто на самом деле:

enum = [*'a'..'z', *'A'..'Z', *0..9].shuffle.permutation 
enum.next.join 
=> "qmrbSTBu6gGpMs4Jh0VZAiI9cW58jxoDz2NwL1eUClaFtdRXfPEOYQnvkKy7H3" 

Это обеспечивает factorial(62) Uniq струнные/UIDs. (Очень большое число!)

Вы также можете указать предел permutation, если хотите более короткие строки/uids, однако это уменьшит количество строк uniq/uids, которые вы можете сгенерировать.

enum = [*'a'..'z', *'A'..'Z', *0..9].shuffle.permutation(13) 
enum.next.join 
=> "A1BD3qljTKpOm" 

Если вы беспокойство по поводу безопасности, то, перемешайте массив с безопасными случайными семенами:

ary = [*'a'..'z', *'A'..'Z', *0..9].shuffle(random: SecureRandom.hex(23).to_i(16)) 
enum = ary.permutation(13) 
enum.next.join 
=> "9bNmv82ruBKjq" 

Уникальность гарантия (таким образом ограниченно), без накладных расходов на вызов базы данных или тестирование уникальность.

+0

- это также возможность декодирования? – Tyler

+0

@TylerRice Не могли бы вы подробнее рассказать, расшифровать, что именно? Никто не сможет угадать следующую последовательность, если это то, что вы имеете в виду, для выполнения любой попытки сначала потребуется случайное «семя», а потому, что «семя» генерируется динамически, получить его будет очень сложно. – yeyo

+0

oh ok ... Я понимаю, что это делает сейчас ....Я думал по линии с идентификатором целого числа и превратил это в хэш, а затем смог его декодировать обратно до целого id – Tyler

3

использовать библиотеку SecureRandom. Он не гарантирует уникальные значения, поэтому перед назначением new_id вам нужно сделать Model.exists? (Field_name: new_id).

def generate_random_id 
     loop do 
     random_number = SecureRandom.hex(10) 
     break random_number unless User.exists?(random_id: random_number) 
     end 
    end 

http://ruby-doc.org/stdlib-2.1.2/libdoc/securerandom/rdoc/SecureRandom.html

ли это ответ на ваш вопрос?

+0

позволяет ли это использовать буквенно-цифровые символы или просто цифры? Мне действительно нужно сделать это как можно короче для URL-адресов, потому что я буду отправлять текстовые сообщения с этими URL-адресами – Tyler

+0

, которые вы хотите их декодировать? –

+0

да если возможно – Tyler

0

Просто если вы хотите использовать символы, то,

('a'..'z').to_a.shuffle[0..7].join 

вы можете изменить длину, как вам будет нужно.

('a'..'z').to_a.shuffle 
=> ["c", "g", "l", "k", "h", "z", "s", "i", "n", "d", "y", "u", "t", "j", "q", 
"b", "r", "o", "f", "e", "w", "v", "m", "a", "x", "p"]