用函数来实现一一对应
$ irb
irb(main):003:0> "aa".hash
=> 3777933626280241396
irb(main):004:0> exit
$ irb
irb(main):001:0> "aa".hash
=> -2547269650278437418
irb(main):002:0>
The hash value for an object may not be identical across invocations or implementations of ruby. If you need a stable identifier across ruby invocations and implementations you will need to generate one with a custom method.
这样?
Digest::MD5.hexdigest("abcde").unpack("Q")[0]
或者:
Digest::MD5.hexdigest("c").to_i 16
一一映射是不太可能的吧,理由 18 楼讲了。就算用 to_i(16)
转成数字,因为绝大多数 cpu 都不是 128 位的,无法原生支持 128 位数字的运算,还是需要把 128 位分成几段来操作。Ruby 用 Bignum 表示大数,楼主正好可以测试一下 Bignum 的性能。
如果是搜索一个文本字段,数据库内建的哈希索引就可以了,不需要自己算 md5 啊。
如果是 mongodb, 截取 12 字节设成 id 存进去也行 (digest[0...24].to_i 16
), 也算是保留了哈希索引,还有自动 sharding, 不过每个记录都得是个数组。
如果硬要转整型字段,截取 8 字节也行 (digest[0...16].to_i 16
), 不过一般数据库对整数字段的索引默认是二叉的,往往还没哈希索引快。
如果是做反查 md5 用,数据海量,最好不要用现成数据库,自己建索引吧