如何在Python中有效地获取唯一ID?

时间:2015-03-23 11:06:49

标签: python django

我希望每个用户都拥有唯一个人识别码,并使用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

我希望能够在这里完成两件事:

  1. 有效地执行此操作
  2. 从PIN中删除 5,S,0,O,1,I

    1. while循环是为了确保PIN是唯一的,但是,这有效地实现了我想要的效果,但我认为它效率不高,因为如果我有1亿用户,它必须达到1亿条记录。 如何以最有效的方式完成这项工作?
    2. 如果没有上述数字和字母,我如何实现这种独特性?

1 个答案:

答案 0 :(得分:1)

重新引用我的评论:

uuid.hex返回十六进制编码,因此您只有[0-9a-f]。因此,甚至不会出现删除指定字符的要求。

但是,使用六个十六进制数字,从一开始就只能提供16 ^ 6 = 16,777,216个可能的PIN。因此,对于1亿用户,您耗尽PIN码(并且无限循环)。

一般情况下,我只是建议选择足够大的PIN空间,并在可能的情况下通过应用程序设计放弃使用唯一PIN的要求。

如果您想要1亿多用户,则需要在您的PIN空间中足够的空间,以便随机数生成太频繁。这是相当模糊的,所以让我们想出一些数字:

当您拥有nu现有用户的固定空间时,从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))