这是一个 Python 函数,用于为 UUID 生成我自己的特定类型(关于为什么我不能使用 uuid.uuid1()
说来话长):
def uuid():
sec = hex(int(time()))[2:]
usec = hex(datetime.now().microsecond)[2:]
rand = hex(choice(range(256)))[2:]
return upper(sec + usec + rand)
# 534AD79CDF1D27
现在,让我们让它运行很长时间,看看我们是否发现任何重复:
UUIDs Duplicates
100000 2
200000 8
300000 8
400000 8
500000 8
600000 9
700000 9
800000 9
900000 9
1000000 10
1100000 14
1200000 14
1300000 14
1400000 17
1500000 17
1600000 18
1700000 21
1800000 24
1900000 24
2000000 27
是的!实际上有近 30 个重复项……现在,这是一个末尾没有随机字节的新函数:
def uuid():
sec = hex(int(time()))[2:]
usec = hex(datetime.now().microsecond)[2:]
return upper(sec + usec)
#534ADA2AC4A41
让我们看看现在有多少重复:
UUIDs Duplicates
100000 0
200000 0
300000 0
400000 0
500000 0
600000 0
700000 0
800000 0
900000 0
1000000 0
1100000 0
1200000 0
1300000 0
1400000 0
1500000 0
1600000 0
1700000 0
1800000 0
1900000 0
2000000 0
嗯,你会看吗?没有一个重复!另外,如果您对我如何确定重复次数感到好奇,这里是代码:
len([x for x, y in Counter(ids).items() if y > 1])
现在,进入实际问题: 添加随机生成的字节如何增加重复的数量?
最佳答案
问题是您使用的是没有零填充的 hex()
。 hex(int(time()))
基本上总是 8 个 nybbles 长,因为它增加的很慢,所以第一部分是恒定长度。这里的 Nybble 指的是单个十六进制数字。
但是,hex(datetime.now().microsecond)
不是恒定长度。它会在 1 nybble(最多 9 us)到 5 nybble(999999 us)之间变化。如果没有“随机字节”,这不是问题,因为您可以通过截断秒来唯一地获得微秒值。
但是,您的“随机字节”也是在没有任何填充的情况下生成的!因此,您最终可以生成 1 nybble 随机字节或 2 nybble 随机字节。因此,您最终可能会产生更多冲突,因为您可以使用例如生成相同的 uuid 3-nybble usec 和 2-nybble rand,与 4-nybble usec 和 1-nybble rand 一样。因此,例如,这两个是碰撞:
usec = 0xabc
rand = 0xde
和
usec = 0xabcd
rand = 0xe
要解决此问题,请填充所有字符串。这很容易用
format
做到:usec = format(datetime.now().microsecond, '05x') # hexify `microsecond` with 5 fixed hex digits
关于python - 如何添加随机字节*增加*重复?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23046796/