I have a form on a website that takes in some personal information from the visitor. I'm passing this information to another service and I need to assign each one of these form submits a 100 character unique hash to be stored in the DB with the record. What's the optimal way to generate this key and make sure it's unique? It's okay if the key auto-increments.
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
ActiveSupport::SecureRandom.hex(50)
The chance of this not being unique is astronomical.
Alternate simple "does not scale" race condition fail solution.
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
If you really want to make sure, make an unique index on the column, and handle a DB uniqueness error by retrying, similar to my implementation above.
回答2:
The Ruby standard lib has a module for generating GUIDs:
http://ruby-doc.org/stdlib/libdoc/digest/rdoc/classes/Digest/SHA2.html
Example:
Digest::SHA1.hexdigest(Time.now.to_s)
回答3:
If you use a Cipher you can encrypt an always different message to get an always different key:
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"