我想简单地将任意长度的字符串转换为整数值。每个字符串将映射到唯一或甚至非唯一的整数。是否有任何现有的opensource命令执行此操作?
奖励点,如果它是唯一的,例如通过bash命令计算字典顺序。
答案 0 :(得分:13)
使用常用编程语言中的hash
函数时需要注意。将随机种子引入散列函数是很常见的,因此散列值仅对于单个程序执行是唯一的。这可以避免oCert advisory 2011-3中提到的拒绝服务攻击。 (正如该咨询所指出的,2003年在向Usenix提交的一篇论文中描述了这个问题。)
例如,默认情况下,Python散列函数已经随机化,因为v3.3:
$ python3 -c 'from sys import argv;print(hash(argv[1]))' abc
-2595772619214671013
$ python3 -c 'from sys import argv;print(hash(argv[1]))' abc
-6001956461950650533
$ python3 -c 'from sys import argv;print(hash(argv[1]))' abc
-7414807274805087300
$ python3 -c 'from sys import argv;print(hash(argv[1]))' abc
-327608370992723225
# Python2 generates consistent hash values
$ python -c 'from sys import argv;print(hash(argv[1]))' abc
1453079729188098211
$ python -c 'from sys import argv;print(hash(argv[1]))' abc
1453079729188098211
$ python -c 'from sys import argv;print(hash(argv[1]))' abc
1453079729188098211
您可以通过设置PYTHONHASHSEED
environment variable。
或者您可以使用SHA-1等标准化加密哈希。常用的sha1sum
实用程序以十六进制输出其结果,但您可以使用bash将其转换为十进制(截断为64位):
$ echo $((0x$(sha1sum <<<"string to hash")0))
-7037254581539467098
或以其完整的160位荣耀,使用bc
(需要以大写形式写入hex):
$ bc <<<ibase=16\;$(sha1sum <<<"string to hash"|tr a-z A-Z)0
861191872165666513280590001082621748432296579238
如果您只需要以16的幂为模的散列值,则可以使用SHA-1总和的前几个字节。 (您可以使用任何选择的字节 - 它们同样分布均匀 - 但前几个更容易提取):
$ echo $((0x$(sha1sum <<<"string to hash"|cut -c1-2)))
150
注意:由于@gniourf_gniourf在注释中指出,上面并没有真正计算给定字符串的SHA-1校验和,因为bash here-string语法( <<<word
)向word
添加换行符。由于附加了换行符的字符串的校验和与字符串本身的校验和一样好,所以只要您始终使用相同的机制来生成散列就没有问题。
答案 1 :(得分:8)
您可以使用sum
或cksum
命令(latter being preferred)生成基数为10的整数:
$ cksum <<< 'hello world' | cut -f 1 -d ' '
3733384285
$ cksum <<< 'goodbye world' | cut -f 1 -d ' '
2600070097
如果您对这些简单哈希背后的数学感兴趣,请查看源代码实现:
-r
和-s
命令行参数。