我希望每个用户都拥有唯一个人识别码,并使用uuid
实现此目的,如下所示:
from myApp.models import myUsers
import uuid
user_PIN = True
new_PIN = uuid.uuid4().hex[:6].upper()
while user_PIN:
try:
user_PIN = myUsers.objects.get(pin = new_PIN)
except myUsers.DoesNotExist:
user_PIN = False
new_PIN = uuid.uuid4().hex[:6].upper()
if not user_PIN:
break
我希望能够在这里完成两件事:
while
循环是为了确保PIN是唯一的,但是,这有效地实现了我想要的效果,但我认为它效率不高,因为如果我有1亿用户,它必须达到1亿条记录。
如何以最有效的方式完成这项工作?答案 0 :(得分:1)
重新引用我的评论:
uuid.hex
返回十六进制编码,因此您只有[0-9a-f]。因此,甚至不会出现删除指定字符的要求。
但是,使用六个十六进制数字,从一开始就只能提供16 ^ 6 = 16,777,216个可能的PIN。因此,对于1亿用户,您将耗尽PIN码(并且无限循环)。
一般情况下,我只是建议选择足够大的PIN空间,并在可能的情况下通过应用程序设计放弃使用唯一PIN的要求。
如果您想要1亿多用户,则需要在您的PIN空间中足够的空间,以便随机数生成太频繁。这是相当模糊的,所以让我们想出一些数字:
当您拥有n
和u
现有用户的固定空间时,从n
生成随机数将产生不存在的PIN (n - u) / n
次。添加l
- 次循环,需要l
循环的概率为((u / n) ** (t - 1)) * ((n - u) / n)
(即选择现有数字t - 1
次的概率,最后获得不存在的数字。
现在,使用6个字符的PIN并且提到的字符被删除,您的字母表可能类似于:
alphabet = 'abcdefghijkmnpqrtuvwxyz2346789'
这会为您提供30
个字符,如果您有6个数字的个人识别码,则可能会有30 ** 6 =
729,000,000
个可能的个人识别码。因此,当用户空间达到1亿时,首次尝试生成唯一的PIN将在1/7
所有可能的情况下失败。
然而,瓶颈将是检查新生成的PIN是否已存在。在一个包含1亿个数字的表中搜索一个数字,这绝不是一个快速的操作。
至于在字母表上生成唯一字符串:使用random.choice()
:
import random
pin_length = 6
random_pin = ''.join(random.choice(alphabet) for i in xrange(0, pin_length))