Bash,如何哈希值的字符串?

时间:2015-03-04 00:14:13

标签: string bash

我想简单地将任意长度的字符串转换为整数值。每个字符串将映射到唯一或甚至非唯一的整数。是否有任何现有的opensource命令执行此操作?

奖励点,如果它是唯一的,例如通过bash命令计算字典顺序。

2 个答案:

答案 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

来控制Python中的哈希随机化

或者您可以使用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)

您可以使用sumcksum命令(latter being preferred)生成基数为10的整数:

$ cksum <<< 'hello world' | cut -f 1 -d ' '
3733384285

$ cksum <<< 'goodbye world' | cut -f 1 -d ' '
2600070097

如果您对这些简单哈希背后的数学感兴趣,请查看源代码实现: