這是一個古老的問題,但任何人都可以尋找另一種解決方案。
一種方法是使用簡單而快速的替換密碼。 (下面的代碼是基於別人的代碼 - 我忘了,我把它從所以不能給予適當的信貸。)
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