2010-01-24 2 views
9

Ich habe ein Formular auf einer Website, das einige persönliche Informationen vom Besucher aufnimmt. Ich übergebe diese Information an einen anderen Dienst und ich muss jedem dieser Formular-Submits einen eindeutigen 100-Zeichen-Hash zuordnen, der in der Datenbank mit dem Datensatz gespeichert wird. Was ist der optimale Weg, um diesen Schlüssel zu generieren und sicherzustellen, dass er einzigartig ist? Es ist in Ordnung, wenn der Schlüssel automatisch erhöht wird.Jedem Benutzer einen eindeutigen Hash mit 100 Zeichen in Ruby on Rails zuweisen

Antwort

22
ActiveSupport::SecureRandom.hex(50) 

Die Wahrscheinlichkeit, dass dies nicht einzigartig ist, ist astronomisch.

Alternative einfache "nicht skalieren" Race Condition Fail-Lösung.

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 

Wenn Sie wirklich sicherstellen möchten, einen eindeutigen Index für die Spalte machen, und eine DB von erneuten Versuch, ähnlich wie meine Implementierung über Einzigartigkeit Fehler behandeln.

+3

In Rails über 3.1 wurde dies nur "SecureRandom.hex (50)". – Bulat

+1

Zwei Dinge erwähnenswert, blies nur 10 Minuten: 1. 'SecureRandom.hex (n)' verdoppelt 'n' als Zeichenlänge im generierten Code (so nichts über 120 oder was auch immer für Postgres String-Typen) 2. Vergessen Sie nicht, Ihr Modell nach der Zuweisung des Wertes zu speichern! (Duh) –

0

Wenn Sie eine Cipher können Sie immer wieder anders Nachricht verschlüsseln eine immer wieder anders zu bekommen Schlüssel:

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"