创建一个唯一的哈希

时间:2014-12-20 21:10:18

标签: ruby-on-rails ruby ruby-on-rails-4 hash

我需要创建一个与数据库中的ID对应的唯一哈希。我是否应该生成随机的字母数字哈希,然后将其存储在数据库中的特定行中?

现在这就是我正在做的事情,但我需要确保人们无法弄清楚创建这些哈希值的算法。

params[:slug].to_i(36)

id.to_s(36)

3 个答案:

答案 0 :(得分:5)

实际上非常简单:

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

这提供了 factorial(62) uniq strings / uids。 (非常多!)

如果你想要更短的字符串/ uid,你也可以提供permutation的限制,但这会减少你可以生成的uniq字符串/ uid的数量。

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"

唯一性是保证(因此受限制),没有调用数据库或测试唯一性的开销。

答案 1 :(得分: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

这会回答你的问题吗?

答案 2 :(得分: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"]