Python中十六进制转字符串格式化转换
我以前是用以下方法生成随机字符串的(现在我改用了这个方法)。
key = '%016x' % random.getrandbits(128)
通过这种方式生成的密钥通常是32个字符的字符串,但有一次我得到了31个字符。
我不明白的是:为什么是32个字符,而不是16个? 难道一个十六进制数字不是只需要一个字符来表示吗?
所以如果我要求%016x
- 难道不应该得到16个字符,前面可能有零吗?
为什么字符串的长度不总是相同的?
测试案例
import random
import collections
stats = collections.defaultdict(int)
for i in range(1000000):
key = '%016x' % random.getrandbits(128)
length = len(key)
stats[length] += 1
for key in stats:
print key, ' ', stats[key]
输出:
32 937911
27 1
28 9
29 221
30 3735
31 58123
2 个回答
3
每个十六进制字符从0到F都包含4位信息,也就是半个字节。128位等于16个字节,而打印一个字节需要两个十六进制字符,所以你会得到32个字符。因此,你的格式字符串应该是'%032x'
,这样总是会生成一个32个字符的字符串,绝不会短。
jkugelman$ cat rand.py
#!/usr/bin/env python
import random
import collections
stats = collections.defaultdict(int)
for i in range(1000000):
key = '%032x' % random.getrandbits(128)
length = len(key)
stats[length] += 1
for key in stats:
print key, ' ', stats[key]
jkugelman$ python rand.py
32 1000000
6
是的,不过你现在用的格式并不会截断数据。你生成了128个随机位,这通常需要32个十六进制数字来表示。而%016
的意思是至少要16个十六进制数字,但它不会自动丢掉多余的数字,因为你需要显示完整的128位数字。那为什么不直接生成64个随机位呢?这样对随机生成器来说工作量更小,而且也不会有格式问题。
顺便说一下,长度有时会是31位,因为每16次中就有1次最高的4位会全是0;实际上,每256次中会有1次最高的8位全是0,这样你就只会得到30位数字,等等。你只要求16位数字,所以格式化会给出大于等于16的最小数字,并且不会进行你没有要求的截断。