我使用以下内容生成一组随机字符和数字:
tag = ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(36)])
我认为这是一个不错的方法。 36个字符长度,每个字符是36个独特选项之一。应该是一个很好的随机性,对吗?
然后,我正在使用我认为是唯一tag
的实例运行查询。事实证明, SEVEN(7)记录具有相同的"随机" tag
。所以,我打开了数据库,并运行了一个查询来查看我的标签的可重复性。
事实证明,我的不仅会出现7次,而且会有一些标签反复出现。大约有2000行,显然不应该发生这种情况。
两个问题:
(1)我的方法出了什么问题,为什么会经常重复相同的tag
?
(2)为每条记录获取唯一标记的更好方法是什么?
以下是我用来将其保存到数据库的代码。虽然它是用Django编写的,但显然这不是与django相关的问题。
class Note(models.Model):
...
def save(self, *args, **kwargs):
import random
import string
self.tag = ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(36)])
super(Note, self).save(*args, **kwargs)
答案 0 :(得分:1)
您的方法存在问题:
更好的解决方案是不重新发明轮子,并使用uuid模块,这是生成唯一标识符的常用解决方案:
import uuid
tag = uuid.uuid1()
答案 1 :(得分:0)
使用加密安全的PRNG和random.SystemRandom()
。它将使用你所使用的任何系统的PRNG。
tag = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits) for n in xrange(36))
请注意,无需将此作为列表理解传递给join()
。
62 36 可能的组合,一个65位的数字,所以即使考虑birthday paradox,重复也应该非常少见。