这是一个古老的问题,但任何人都可以寻找另一种解决方案。
一种方法是使用简单而快速的替换密码。 (下面的代码是基于别人的代码 - 我忘了,我把它从所以不能给予适当的信贷。)
class Array
def shuffle_with_seed!(seed)
prng = (seed.nil?) ? Random.new() : Random.new(seed)
size = self.size
while size > 1
# random index
a = prng.rand(size)
# last index
b = size - 1
# switch last element with random element
self[a], self[b] = self[b], self[a]
# reduce size and do it again
size = b;
end
self
end
def shuffle_with_seed(seed)
self.dup.shuffle_with_seed!(seed)
end
end
class SubstitutionCipher
def initialize(seed)
normal = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a + [' ']
shuffled = normal.shuffle_with_seed(seed)
@map = normal.zip(shuffled).inject(:encrypt => {} , :decrypt => {}) do |hash,(a,b)|
hash[:encrypt][a] = b
hash[:decrypt][b] = a
hash
end
end
def encrypt(str)
str.split(//).map { |char| @map[:encrypt][char] || char }.join
end
def decrypt(str)
str.split(//).map { |char| @map[:decrypt][char] || char }.join
end
end
你使用这样的:
MY_SECRET_SEED = 3429824
cipher = SubstitutionCipher.new(MY_SECRET_SEED)
id = hash["_id"].to_s
encrypted_id = cipher.encrypt(id)
decrypted_id = cipher.decrypt(encrypted_id)
请注意,这是只会加密az,AZ,0-9和一个空格,使其他字符保持不变。 BSON ID足够了。
你也可以base64编码,大约有16个字符。或base85有12左右。 – Tower 2012-04-19 06:17:25
ObjectIds是否“容易”猜测取决于谁在猜测。对于一个偶然的网络浏览器来说,不,但对于任何值得他们加盐的黑客来说,这些都是微不足道的猜测。如果您需要安全的ID,请不要使用ObjectIds,basewhatever-encoded或其他方式 - 使用像安全生成的UUID一样真正随机的东西。 – Leopd 2013-04-09 16:07:41