【问题标题】:Python - Create million of unique alphanumeric codes with high performancePython - 创建数百万个高性能的独特字母数字代码
【发布时间】:2017-06-15 10:14:36
【问题描述】:

实际上,我被以下业务案例所困扰,不知道如何解决它。

我必须创建超过 5.000.000 个唯一的字母数字代码。

代码规则如下:

length: 12
format: every 4 digits "-"
some letters should be excluded like: O or l

代码应该是“安全的”(即完全随机),并且应该可以多次运行脚本,以防代码不够,我们必须创建更多代码。

例如ab4D-406a-BCh7-TEs3

我必须在 Python 3 中解决这个问题。

我的第一个想法是将代码保存到数据库中,然后使用随机函数 ASCII-Code -> Letter 创建它们,但也许脚本会创建两次相同的代码,所以我必须每次检查该代码是否已经存在会导致大量数据库流量的数据库。

我的第二个想法是使用哈希函数,但我认为代码不安全,并且没有符合我规则的哈希函数。

我的第三个想法是使用类似于 python 中的随机模块的方式来创建代码并将代码写入文件,如果代码已经在其中,则每次检查文件。但这也不利于性能,但我认为比使用数据库更好。

有人知道如何以高性能解决这个问题吗?

您好。

编辑:

我试过了,但创建代码需要几个小时。一些技巧如何提高性能?

import random

sequence = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
seq = list(sequence)


codelist = []
counter = 0
while len(codelist) < 5000000:
    code = ""
    counter = counter +1
    print(counter)
    while len(code) < 12:
        code = code + str(random.choice(seq))

    try:
        codelist.index(code)
    except ValueError:
        codelist.append(code)


file = open('codefile.txt','w')
for item in codelist:
    file.write("%s\n" % item)

【问题讨论】:

  • 你说有些字符需要排除?假设剩下 50 个字符。这产生了 244x10^18 的可能性。是什么阻碍了您立即随机创建它们,然后转储它们并检查非唯一条目?双打的机会似乎很小......如果你找到双打,删除它们并为那些被删除的生成一个新的。也许丑陋,但一旦它在数据库中,一切都应该足够快......
  • 我不明白。 ab4D-406a-BCh7-TEs3 有 16 位数字,不包括 -,但你说你想要长度为 12。
  • 您应该记住,如果您生成由四个字母组成的无限代码,您将进入猴子与打字机的场景。您的某些代码可能类似于莎士比亚,但其他代码最终可能非常粗俗和/或令人反感。
  • 没想到。很好的评论谢谢!

标签: python performance random cryptography alphanumeric


【解决方案1】:

加密保证唯一性。如果您加密数字 0、1、2、... 5,000,000,您将获得 5,000,001 个保证的唯一结果,前提是您不更改密钥。

您的下一个问题是如何将生成的二进制数更改为您想要的格式。完整的字母数字使用 26 + 26 + 10 = 62 个字符。您正在使用其中的一个子集,因此您将使用更少的字符,例如 58 个字符。这意味着您可以将输出视为 12 位以 58(或其他)为基数的数字。

以 58 为基数(或其他)的 12 位数字将允许您调整您加密的二进制块的大小。查看Format Preserving Encryption 以确保您的加密输出大小符合您的要求。

【讨论】:

    【解决方案2】:

    生成唯一字母数字代码的最简单方法是生成 uuid,但它们与您的“规则”不匹配 - 它们更长:

    >>> import uuid
    >>> _id = uuid.uuid4()
    >>> print (_id)
    5d9efd48-661f-47f8-8886-13e93fd8b899
    >>> print (len(str(_id)))
    36
    >>> 
    

    【讨论】:

    • 如果你修剪,你会失去 UUID 的 UU 部分,即唯一性
    【解决方案3】:
    from threading import Thread
    
    UUIDs = []
    for i in range(100):
        t = Thread(target= generate_alphanum, args=(UUIDs,))
        t.start()
    def generate_alphanum(g_list):
        while len(g_list) < 50000:
            uid = ''.join(random.choice(string.ascii_letters + string.digits[2:]) for _ in range(12))
            if uid not in g_list:
                g_list(uid[:4] + '-' + uid[4:8] + '-' + uid[8:])
    

    注意:这可能无法保证完全随机,但可以完成工作。 样本输出:

    'FD58-KGIo-yBGL',
     'q9jv-tDa4-K3ae',
     'BrGr-AO9o-GkfN',
     'VyKb-NHh2-HRHM',
     'g3Eu-aPsv-2YgF',
     'iPxB-p4GV-f5tM',
     'jewn-NWnM-kUDw',
     'gDWY-MZB4-OysT',
     'Acbu-kpTG-TCMm',
     'rHBz-yJca-s9aA',
     '2nnH-WFgT-gQef',
     '2qSz-kX8z-qDpi',
     'FnjV-sgzj-gzWt',
     '5uwW-jwM5-FxB6',
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-17
      • 1970-01-01
      • 1970-01-01
      • 2013-11-27
      • 2021-07-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多