我需要在 Ruby 中为变量创建签名字符串,其中变量可以是数字、字符串、哈希值或数组。哈希值和数组元素也可以是这些类型中的任何一种。
该字符串将用于比较数据库(在本例中为 Mongo)中的值。
我的第一个想法是创建 JSON 编码值的 MD5 哈希,如下所示:(body 是上面提到的变量)
def createsig(body)
Digest::MD5.hexdigest(JSON.generate(body))
end
这几乎可以工作,但是 JSON.generate 不会每次都以相同的顺序对哈希的键进行编码,因此createsig({:a=>'a',:b=>'b'})
并不总是等于createsig({:b=>'b',:a=>'a'})
.
创建签名字符串来满足此需求的最佳方法是什么?
注意:对于我们之间注重细节,我知道你不能JSON.generate()
一个数字或一个字符串。在这些情况下,我只会打电话MD5.hexdigest()
直接地。
我很快就编写了以下代码,没有时间在工作中真正测试它,但它应该可以完成工作。如果您发现任何问题,请告诉我,我会查看。
这应该正确地展平并对数组和散列进行排序,并且您需要一些看起来非常奇怪的字符串才能避免任何冲突。
def createsig(body)
Digest::MD5.hexdigest( sigflat body )
end
def sigflat(body)
if body.class == Hash
arr = []
body.each do |key, value|
arr << "#{sigflat key}=>#{sigflat value}"
end
body = arr
end
if body.class == Array
str = ''
body.map! do |value|
sigflat value
end.sort!.each do |value|
str << value
end
end
if body.class != String
body = body.to_s << body.class.to_s
end
body
end
> sigflat({:a => {:b => 'b', :c => 'c'}, :d => 'd'}) == sigflat({:d => 'd', :a => {:c => 'c', :b => 'b'}})
=> true
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)