Python中的唯一会话ID
我该如何在Python中生成一个唯一的会话ID?
5 个回答
35
Python 3.6 版本让这里的大部分回答都有点过时了。从 3.6 及以后的版本开始,Python 增加了一个叫做 secrets
的模块,这个模块就是为了这个目的而设计的。
如果你需要在网上生成一个安全的字符串,可以参考这个模块。
https://docs.python.org/3/library/secrets.html
示例:
import secrets
def make_token():
"""
Creates a cryptographically-secure, URL-safe string
"""
return secrets.token_urlsafe(16)
使用示例:
>>> make_token()
'B31YOaQpb8Hxnxv1DXG6nA'
79
更新:2016-12-21
在过去的五年里,发生了很多事情。/dev/urandom
已经更新,现在被认为是现代Linux内核和发行版中一个高熵的随机数来源。在过去的六个月里,我们在使用Ubuntu的Linux 3.19内核上遇到了熵不足的问题,所以我认为这个问题并没有“解决”,但在向操作系统请求任何数量的随机数时,得到低熵的随机数是相当困难的。
我不想这么说,但这里其他的解决方案都不适合用作“安全会话ID”。
# pip install M2Crypto
import base64, M2Crypto
def generate_session_id(num_bytes = 16):
return base64.b64encode(M2Crypto.m2.rand_bytes(num_bytes))
无论是 uuid()
还是 os.urandom()
都不是生成会话ID的好选择。虽然它们可能会生成随机的结果,但随机并不意味着它是安全的,因为熵不足。可以参考 Haldir 的文章 "如何破解线性同余生成器" 或者 NIST关于随机数生成的资源。如果你仍然想使用UUID,那么请使用一个用良好的初始随机数生成的UUID:
import uuid, M2Crypto
uuid.UUID(bytes = M2Crypto.m2.rand_bytes(num_bytes)))
# UUID('5e85edc4-7078-d214-e773-f8caae16fe6c')
或者:
# pip install pyOpenSSL
import uuid, OpenSSL
uuid.UUID(bytes = OpenSSL.rand.bytes(16))
# UUID('c9bf635f-b0cc-d278-a2c5-01eaae654461')
M2Crypto 是目前Python中最好的OpenSSL API,因为pyOpenSSL似乎只是为了支持旧应用程序而维护。
31
你可以这样使用 uuid库:
import uuid my_id = uuid.uuid1() # or uuid.uuid4()