我正在使用一个名为21 char max的api代表一个内部会话,其寿命大约为"两天".我希望这个名字不是有意义的使用某种哈希?md5生成40个字符,还有其他我可以使用的吗?
现在我使用'userid [:10]'+创建时间:ddhhmmss +随机3个字符.
谢谢,
如果我正确地读了你的问题,你想要生成一些任意标识符标记,最多必须是21个字符.是否需要高度猜测?你给出的例子不是"密码学强",因为可以通过搜索整个可能的密钥空间的1/2来猜测它.
您没有说明字符是否可以是所有256个ASCII字符,或者是否需要限制为可打印的ASCII(33-127,包括端点)或更小的范围.
有一个为UUID(Universals Unique IDentifiers)设计的Python模块.您可能希望uuid4生成随机UUID,如果可用,则使用OS支持(在Linux,Mac,FreeBSD以及其他可能的其他用户).
>>> import uuid >>> u = uuid.uuid4() >>> u UUID('d94303e7-1be4-49ef-92f2-472bc4b4286d') >>> u.bytes '\xd9C\x03\xe7\x1b\xe4I\xef\x92\xf2G+\xc4\xb4(m' >>> len(u.bytes) 16 >>>
16个随机字节是非常不可取的,如果你想要的是拥有一个不可思议的不透明标识符,就不需要使用API允许的完整21个字节.
如果你不能像这样使用原始字节,这可能是一个坏主意,因为它更难在日志和其他调试消息中使用,并且更难以通过眼睛比较,然后将字节转换为更具可读性的东西,如使用base- 64位编码,结果被砍掉为21(或其他)字节:
>>> u.bytes.encode("base64") '2UMD5xvkSe+S8kcrxLQobQ==\n' >>> len(u.bytes.encode("base64")) 25 >>> u.bytes.encode("base64")[:21] '2UMD5xvkSe+S8kcrxLQob' >>>
这为您提供了一个非常高质量的长度为21的随机字符串.
您可能不喜欢可能位于base-64字符串中的'+'或'/',因为没有可能会干扰URL的正确转义.既然你已经想过使用"随机3个字符",我认为这不是你的担心.如果是,您可以用其他东西替换这些字符(' - '和'.'可能有效),或者删除它们(如果存在).
正如其他人所指出的那样,你可以使用.encode("hex")并获得十六进制等值,但是只有4位的随机性/字符*21个字符最大值可以得到84位的随机性而不是两倍.每一位都会使你的键空间翻倍,使理论搜索空间变得更小,更小.由2E24倍减小.
你的密钥空间大小仍然是2E24,即使是十六进制编码,所以我认为它更像是一个理论上的问题.我不担心人们对你的系统进行暴力攻击.
编辑:
PS:uuid.uuid4函数使用libuuid(如果可用).从当前时间和本地以太网MAC地址获取os.urandom(如果可用)的熵.如果libuuid不可用,那么uuid.uuid4函数直接从os.urandom获取字节(如果可用),否则它使用随机模块.随机模块使用基于os.urandom(如果可用)的默认种子,否则使用基于当前时间的值.探测发生在每个函数调用中,因此如果您没有os.urandom,那么开销会比您预期的要大一些.
带回家留言?如果你知道你有os.urandom那么你就可以做到
os.urandom(16).encode("base64")[:21]
但如果您不想担心其可用性,请使用uuid模块.