python中的十六进制到字符串格式转换

时间:2009-07-10 01:56:21

标签: python string

我曾经用以下方式生成随机字符串(现在我已切换到this method)。

key = '%016x' % random.getrandbits(128)

以这种方式生成的密钥通常是32个字符的字符串,但是一旦我有31个字符。

这是我没有得到的:为什么它是32个字符,而不是16个?一个十六进制数字是否需要打印一个字符?

所以,如果我要求%016x - 不应该期望十六个字符可能带有前导零吗?

为什么字符串legth并不总是相同?

测试用例

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

答案 0 :(得分:6)

是的,但您使用的格式不会截断 - 您生成128个随机位,这需要(通常)32个十六进制数字来显示,%016表示至少16个十六进制数字,但是不只是丢掉你需要的额外的那些来显示所有128位数字。如果那是你真正需要的,为什么不生成64个随机位?随机生成器的工作量减少,没有格式化问题。

为了满足您的好奇心,长度偶尔为31位,因为16位中的1位时间前4位将全部为0;实际上在256中有1次,所有前8位都是0,所以你只能获得30位数等等。你只需要16位数字,所以格式化的数量最少的是> = 16而不是要求截断你没有要求。

答案 1 :(得分: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