2010-01-24 9 views
9

Mam formularz na stronie internetowej, która pobiera pewne dane osobowe od odwiedzających. Przekazuję tę informację do innej usługi i muszę przypisać każdą z tych formularzy, składającą unikatowy skrót o długości 100 znaków, który będzie przechowywany w bazie danych z rekordem. Jaki jest optymalny sposób wygenerowania tego klucza i upewnienia się, że jest wyjątkowy? Jest w porządku, jeśli klucz automatycznie się zwiększa.Przypisywanie każdemu użytkownikowi unikalnego 100-znakowego hasza w Ruby on Rails

Odpowiedz

22
ActiveSupport::SecureRandom.hex(50) 

Szansa na to, że nie jest wyjątkowa, jest astronomiczna.

Alternatywne proste rozwiązanie problemu "nie skaluje".

class MyModel < ActiveRecord::Base 
    before_create :assign_unique_token 

    private 

    def assign_unique_token 
    self.unique_token = ActiveSupport::SecureRandom.hex(50) until unique_token? 
    end 

    def unique_token? 
    self.class.count(:conditions => {:unique_token => unique_token}) == 0 
    end 
end 

Jeśli naprawdę chcesz się upewnić, zrobić unikatowy indeks na kolumnie i obsługiwać DB unikatowości błąd poprzez ponowną próbą, podobnym do mojego realizacji powyżej.

+3

W Railsach powyżej 3.1 stało się to po prostu "SecureRandom.hex (50)". – Bulat

+1

Dwie rzeczy, o których warto wspomnieć, po prostu dmuchnęły 10 min lub tak: 1. 'SecureRandom.hex (n)' podwaja 'n' jako długość znaku w wygenerowanym kodzie (więc nic ponad 120 lub cokolwiek w przypadku typów łańcuchów Postgres) 2. Nie zapomnij zapisać modelu po przypisaniu wartości! (duh) –

0

Jeśli używasz szyfr można zaszyfrować zawsze inny komunikat, aby uzyskać zawsze inny klucz:

def encrypt(data, key, cipher_type) 
    aes = OpenSSL::Cipher::Cipher.new(cipher_type) 
    aes.encrypt 
    aes.key = key 
    aes.update(data) + aes.final  
    end 

>> Base64.encode64(encrypt(Time.now.to_s, "some_key_long_enough_for_the_job", "AES-256-ECB")) 
=> "sKJU3qhszV30Ya9vMFvbqIXus+QygICdDyr7UQFWLeM=\n"