python hash 每次调用结果不一样
import time
import multiprocessing
device = ['3695a1c7-0fa6-4fa8-a563-8fd462c04af5', '0dfdd431-f9bc-4c90-b246-f2b19d20969c', '0323488d-7c9c-4244-8fc6-07266124d2f0', '689cde3c-6ca4-4ed7-b63a-e114b76650fb', 'bc4084a5-da8e-4673-a214-4b5f5de4b21d', 'b6ec0d69-af49-43d1-b77d-e72da48df2e6', 'a7fe06e8-ff26-4ebf-b526-ca7083ccb031', '7a8db973-6a7b-481b-ba80-0afb5594b6cd', '637db54f-9932-4d8e-8b87-5c92011578e9', '506b79bd-e174-4c24-8e39-9410ef7ef1f2']
def do_hash(d):
print("%s %d %d %d" % (d, hash(d), hash(d), hash(d)%10))
time.sleep(0.01)
res, pool = [], multiprocessing.Pool(processes=len(device))
for d in device:
do_hash(d)
for i in range(10):
res.append(pool.apply_async(do_hash, args=(d,)))
while res:
for ret in res:
if ret.ready():
res.remove(ret)
time.sleep(0.01)
如上代码,用来验证hash
的结果。
- 在同一个程序运行过程中,单进程下,
hash
同一个字符串,结果是否一致。 答案:一致 - 在同一个程序运行过程中,多进程中,不同子进程
hash
同一个字符串,结果是否一致。答案:一致 - 同样的代码,多次运行同一个程序,每次运行程序时,
hash
同一个字符串,产生的结果和其他运行过程产生的结果是否一致。答案:不一致
如下是运行测试。
- 运行一次
$python3 ~/t.py |sort |uniq -c
11 0323488d-7c9c-4244-8fc6-07266124d2f0 -6009992680465351322 -6009992680465351322 8
11 0dfdd431-f9bc-4c90-b246-f2b19d20969c -5508606457111079556 -5508606457111079556 4
11 3695a1c7-0fa6-4fa8-a563-8fd462c04af5 4707712037038632691 4707712037038632691 1
11 506b79bd-e174-4c24-8e39-9410ef7ef1f2 857824721138771069 857824721138771069 9
11 637db54f-9932-4d8e-8b87-5c92011578e9 5754536697633125890 5754536697633125890 0
11 689cde3c-6ca4-4ed7-b63a-e114b76650fb 5254068311346342848 5254068311346342848 8
11 7a8db973-6a7b-481b-ba80-0afb5594b6cd 6569556914358930293 6569556914358930293 3
11 a7fe06e8-ff26-4ebf-b526-ca7083ccb031 -7752949605389894777 -7752949605389894777 3
11 b6ec0d69-af49-43d1-b77d-e72da48df2e6 5391450356066231067 5391450356066231067 7
11 bc4084a5-da8e-4673-a214-4b5f5de4b21d 8663379699579545061 8663379699579545061 1
- 再运行一次:
$ python3 ~/t.py |sort |uniq -c
11 0323488d-7c9c-4244-8fc6-07266124d2f0 6637200495818958087 6637200495818958087 7
11 0dfdd431-f9bc-4c90-b246-f2b19d20969c 2550085777036819750 2550085777036819750 0
11 3695a1c7-0fa6-4fa8-a563-8fd462c04af5 3291757742095134676 3291757742095134676 6
11 506b79bd-e174-4c24-8e39-9410ef7ef1f2 -1500680899775158570 -1500680899775158570 0
11 637db54f-9932-4d8e-8b87-5c92011578e9 -1846084821474967397 -1846084821474967397 3
11 689cde3c-6ca4-4ed7-b63a-e114b76650fb -8218022715868473813 -8218022715868473813 7
11 7a8db973-6a7b-481b-ba80-0afb5594b6cd -783003051379698560 -783003051379698560 0
11 a7fe06e8-ff26-4ebf-b526-ca7083ccb031 -4314803525216302877 -4314803525216302877 3
11 b6ec0d69-af49-43d1-b77d-e72da48df2e6 1699421278255228297 1699421278255228297 7
11 bc4084a5-da8e-4673-a214-4b5f5de4b21d 6135446317717420100 6135446317717420100 0
原因是:
python的字符串hash算法并不是直接遍历字符串每个字符去计算hash,而是会有一个secret prefix和一个secret suffix,可以认为相当于是给字符串加盐后做hash,可以规避一些规律输入的情况显然这个secret前后缀的值会直接影响计算结果,而且它有一个启动时随机生成的机制,只不过,在2.x版本中,这个机制默认是关闭的,前后缀每次启动都设置为0,除非你改了相关环境变量来要求随机,而在3.x中修改了默认行为,如果你不配置环境变量,则默认是随机一个前后缀值,这样每次启动都会不同这个环境变量是PYTHONHASHSEED,无论在2.x还是3.x中,配置为一个正整数,将作为随机种子;配置为0,则secret前后缀默认清零(和2.x默认行为就一样了),配置为空串或“random”,则表示让进程随机生成(和3.x默认行为一样)具体为啥要这么做,猜测一个是为了安全性(防字符串hash表的攻击,比如php曾经碰到的攻击),另一个可能也是强调不要依赖一些内建结果,因为这种算法可能随着版本而更新,避免有些用户不看文档,误以为是永远不变的
作者:冒泡
链接:https://www.zhihu.com/question/57526436/answer/153241020
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
设置固定的PYTHONHASHSEED
后结果一致:
yzc:~ youzhengchuan$ PYTHONHASHSEED=10 python3 ~/t.py |sort |uniq -c
11 0323488d-7c9c-4244-8fc6-07266124d2f0 2141519202912666524 2141519202912666524 4
11 0dfdd431-f9bc-4c90-b246-f2b19d20969c -843959203188636526 -843959203188636526 4
11 3695a1c7-0fa6-4fa8-a563-8fd462c04af5 5124534335560792207 5124534335560792207 7
11 506b79bd-e174-4c24-8e39-9410ef7ef1f2 -8435934314154906615 -8435934314154906615 5
11 637db54f-9932-4d8e-8b87-5c92011578e9 -8619377286856168125 -8619377286856168125 5
11 689cde3c-6ca4-4ed7-b63a-e114b76650fb 9094422155202130727 9094422155202130727 7
11 7a8db973-6a7b-481b-ba80-0afb5594b6cd 1077850608746704706 1077850608746704706 6
11 a7fe06e8-ff26-4ebf-b526-ca7083ccb031 -4716484918100210177 -4716484918100210177 3
11 b6ec0d69-af49-43d1-b77d-e72da48df2e6 -5676381002318020516 -5676381002318020516 4
11 bc4084a5-da8e-4673-a214-4b5f5de4b21d 4107242733003648281 4107242733003648281 1
yzc:~ youzhengchuan$ PYTHONHASHSEED=10 python3 ~/t.py |sort |uniq -c
11 0323488d-7c9c-4244-8fc6-07266124d2f0 2141519202912666524 2141519202912666524 4
11 0dfdd431-f9bc-4c90-b246-f2b19d20969c -843959203188636526 -843959203188636526 4
11 3695a1c7-0fa6-4fa8-a563-8fd462c04af5 5124534335560792207 5124534335560792207 7
11 506b79bd-e174-4c24-8e39-9410ef7ef1f2 -8435934314154906615 -8435934314154906615 5
11 637db54f-9932-4d8e-8b87-5c92011578e9 -8619377286856168125 -8619377286856168125 5
11 689cde3c-6ca4-4ed7-b63a-e114b76650fb 9094422155202130727 9094422155202130727 7
11 7a8db973-6a7b-481b-ba80-0afb5594b6cd 1077850608746704706 1077850608746704706 6
11 a7fe06e8-ff26-4ebf-b526-ca7083ccb031 -4716484918100210177 -4716484918100210177 3
11 b6ec0d69-af49-43d1-b77d-e72da48df2e6 -5676381002318020516 -5676381002318020516 4
11 bc4084a5-da8e-4673-a214-4b5f5de4b21d 4107242733003648281 4107242733003648281 1
yzc:~ youzhengchuan$ PYTHONHASHSEED=10 python3 ~/t.py |sort |uniq -c
11 0323488d-7c9c-4244-8fc6-07266124d2f0 2141519202912666524 2141519202912666524 4
11 0dfdd431-f9bc-4c90-b246-f2b19d20969c -843959203188636526 -843959203188636526 4
11 3695a1c7-0fa6-4fa8-a563-8fd462c04af5 5124534335560792207 5124534335560792207 7
11 506b79bd-e174-4c24-8e39-9410ef7ef1f2 -8435934314154906615 -8435934314154906615 5
11 637db54f-9932-4d8e-8b87-5c92011578e9 -8619377286856168125 -8619377286856168125 5
11 689cde3c-6ca4-4ed7-b63a-e114b76650fb 9094422155202130727 9094422155202130727 7
11 7a8db973-6a7b-481b-ba80-0afb5594b6cd 1077850608746704706 1077850608746704706 6
11 a7fe06e8-ff26-4ebf-b526-ca7083ccb031 -4716484918100210177 -4716484918100210177 3
11 b6ec0d69-af49-43d1-b77d-e72da48df2e6 -5676381002318020516 -5676381002318020516 4
11 bc4084a5-da8e-4673-a214-4b5f5de4b21d 4107242733003648281 4107242733003648281 1
python hash 每次调用结果不一样的更多相关文章
- python与java的内存机制不一样;java的方法会进入方法区直到对象消失 方法才会消失;python的方法是对象每次调用都会创建新的对象 内存地址都不i一样
python与java的内存机制不一样;java的方法会进入方法区直到对象消失 方法才会消失;python的方法是对象每次调用都会创建新的对象 内存地址都不i一样
- Python包模块化调用方式详解
Python包模块化调用方式详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一般来说,编程语言中,库.包.模块是同一种概念,是代码组织方式. Python中只有一种模块对象类型 ...
- Shodan搜索引擎详解及Python命令行调用
shodan常用信息搜索命令 shodan配置命令 shodan init T1N3uP0Lyeq5w0wxxxxxxxxxxxxxxx //API设置 shodan信息收集 shodan myip ...
- python笔记之调用系统命令
python笔记之调用系统命令 目前我使用到的python中执行cmd的方式有三种 使用os.system("cmd") 该方法在调用完shell脚本后,返回一个16位的二进制数, ...
- 每次调用fork()函数之后,父线程和创建出的子线程都是从fork()后开始执行
Linux下多少个"-"将被打印: 1 2 3 4 5 6 7 8 int main(void){ int i; for(i=0;i<4;i++){ fork() ...
- python可变参数调用函数的问题
已使用python实现的一些想法,近期使用python这种出现的要求,它定义了一个函数,第一种是一般的参数,第二个参数是默认,并有可变参数.在第一项研究中python时间,不知道keyword可变参数 ...
- python发布及调用基于SOAP的webservice
现如今面向服务(SOA)的架构设计已经成为主流,把公用的服务打包成一个个webservice供各方调用是一种非常常用的做法,而应用最广泛的则是基于SOAP协议和wsdl的webservice.本文讲解 ...
- python 程序中调用go
虽然python优点很多,但是有一个致命的缺点就是运行速度太慢,那么python程序需要一些计算量比较大的模块时一般会调用c或者c++的代码来重写,但是c/c++编写代码代价太高,耗费太多的人力.那么 ...
- 如何在Python脚本中调用外部命令(就像在linux shell或Windows命令提示符下输入一样)
如何在Python脚本中调用外部命令(就像在linux shell或Windows命令提示符下输入一样) python标准库中的subprocess可以解决这个问题. from subprocess ...
随机推荐
- spring ioc aop 理解
OC,依赖倒置的意思,所谓依赖,从程序的角度看,就是比如A要调用B的方法,那么A就依赖于B,反正A要用到B,则A依赖于B.所谓倒置,你必须理解如果不倒置,会怎么着,因为A必须要有B,才可以调用B,如果 ...
- 修改Vue中的 v-html 内的元素无效问题
其原因就是在 style 样式中没有去处scoped 因为 v-html 会把内容当成子组件,而scoped 会在本身的组件中起作用
- 如何在cmd命令行中运行Java程序
cmd运行java 有萌新问我怎么用cmd运行Java,他运行报错了,怎么办?如图是他的执行过程: 他说就这一个类,里面包含了main方法怎么会没有加载主类呢. 其实很简单,因为你执行的时候并不能直接 ...
- 如果在docker中部署tomcat,并且部署java应用程序
1.先说如何在docker中部署tomcat 第一步:root用户登录在系统根目录下创建文件夹tomcat7,命令如:mkdir tomcat7,并且切换到该目录下:cd tomcat7: 第二步:创 ...
- 检测udp端口
linux 检测端口是否打开:nc -zuv ip 端口 服务器监听端口:nc -l -u ip 端口(可以发送和接受信息) 客户端检测端口:nc -u ip 端口(可以发送和接受信息) 查看监听的t ...
- angular打印功能实现方式
目前主流的前端打印方式有两种:一种是使用浏览器打印功能直接打印页面,另一种是调用本地控件实现.浏览器打印功能单一,不适用于复杂的业务表单,而打印控件可以设计打印模板,实现复杂表单的打印,十分适合复杂的 ...
- 从零开始学会GAN 0:第一部分 介绍生成式深度学习(连载中)
本书的前四章旨在介绍开始构建生成式深度学习模型所需的核心技术.在第1章中,我们将首先对生成式建模领域进行广泛的研究,并从概率的角度考虑我们试图解决的问题类型.然后,我们将探讨我们的基本概率生成模型的第 ...
- Websocket @serverendpoint 404
今天写一个前后端交互的websocket , 本来写着挺顺利的,但测试的时候蒙了,前端websocket发的连接请求竟然连接不上 返回状态Status 报了个404 ,然后看后台onError方法也没 ...
- 根据传入url请求,返回json字符串
/** * 根据传入url请求,返回json字符串 * @param url * @return * @throws UnsupportedEncodingException */ public st ...
- IPC 进程间通信方式——信号量
信号量 本质上是共享资源的数目,用来控制对共享资源的访问. 用于进程间的互斥和同步 每种共享资源对应一个信号量,为了便于大量共享资源的操作引入了信号量集,可对多对信号量一次性操作.对信号量集中所有的操 ...