【问题标题】:How to generate a human friendly unique ID in Python? [closed]如何在 Python 中生成人类友好的唯一 ID? [关闭]
【发布时间】:2011-10-09 08:48:08
【问题描述】:

我如何生成一个可以通过电话或电子邮件轻松传递的唯一 ID 值,该值可以很容易记住,但又不容易被猜到。

我正在使用数据库。但是当我将 ID 泄露给人们时,我不希望它被绑定到数据库。我可以使用我在数据库中已有的唯一 ID 来做一些事情,但不能直接使用它,以避免它被猜到。

我正在使用 Python 并尝试使用 uuid,但 uuid 太长而无法人类阅读

有什么方法可以创建人类友好的可发音 ID?

【问题讨论】:

  • 对哪个基地唯一?您是否有数据库,或者您想创建一个不太可能与以下值发生冲突的随机字符串/数字?请详细说明您的问题。
  • hash(str(your_id))怎么样
  • 您可以去除散列值,但这更容易导致冲突。但这就是你必须处理的问题。没有冲突 -> 不可读,可读 -> 可能发生冲突。

标签: python random unique uniqueidentifier


【解决方案1】:

您要做的是将音节拼接在一起以创建可发音的伪词。您可以用任何您喜欢的语言创建音节,以组成可以发音和交流但实际上没有任何意义的单词。

Here is an article about how one person created human readable UIDs for speaking them phonetically and some of the pitfalls.

阅读上面的链接,了解在采用这种方法时应该考虑的一些陷阱。

您可以只使用一串字母,但将它们显示为 NATO phonetic alphabet 而不仅仅是字母。

【讨论】:

  • 这个故事是真的吗?这不可能是真的。
【解决方案2】:

对于电子邮件,我使用的是:

from base64 import b64encode
from os import urandom
key = b64encode(urandom(9))

您可以通过更改数字来增加/减少长度。 有时你会得到 + 和 / 字符,如果你愿意,你可以去掉它们。

编辑: 由于您还想通过电话传递它们,也许b32encode(urandom(5)) 会是更好的选择,因为它不会给您任何小写或不寻常的字符。

【讨论】:

  • 你能解释一下为什么这是一个坏主意,因为我自己用这个?
【解决方案3】:

像亚马逊的付费短语这样的东西怎么样?将二进制 ID 转换为英文单词序列。

如果您想要与 UUID 具有相同范围的内容,则需要表示 16 个字节。 为了保持合理,将短语限制为 4 个单词,因此每个单词代表 4 个字节,或 65536 种可能性,因此您需要一个包含 262,144 个单词的字典。

编辑: 实际上,经过反思,可能更好的是一种疯狂的 lib 句子——它会限制所需单词的数量,并且可能更容易记住,因为它具有语法结构。当然,它需要更长的时间,也许是这样的:

(a/an/the/#) (adj) (名词) (动词)(时态) (副词) while (a/an/the/#) (adj) (名词) (动词) (副词)。

【讨论】:

  • 或 65536 个字,如果您允许“Foo Foo Foo Foo”作为有效的付费短语。
  • 您的编辑太复杂了。只需加载字典并使用memorable_id = ''.join(dictionary[random.randint(0, 65535)] for Null in range(4)) 会更好。
【解决方案4】:

当然,但它需要对您的问题空间进行更多限制,即:

  1. 只有一件事可以生成唯一 ID
  2. 您的项目有一些标题概念
  3. 您可以保留字符串列表

然后你会做这样的事情:

_UID_INTERNALS = set()

def getID(obj):
    if hasattr(obj, 'UID'):
        return obj.UID
    title = obj.title.encode("ascii", errors="ignore")
    title = title.lower()
    title = "-".join(title.split())
    if not title:
        title = "unnamed-object"
    UID = title
    num = 1
    while UID in _UID_INTERNALS:
        UID = title + str(num)
        num += 1
    _UID_INTERNALS.add(UID)
    obj.UID = UID
    return UID

【讨论】:

  • 同上,这段代码有什么问题?如前所述,它可以完美地工作并解决您的问题。
  • 如果 OP 当前正在使用 UUID,那么几乎可以肯定会有不止一个东西生成唯一 ID,因为它几乎肯定是一个分布式系统。坦率地说,如果您可以集中生成 ID,那么问题就很容易解决。
  • OP 使用 uuid 是因为抗猜测。事实上,正如他们所说,他们已经有一个具有唯一 ID 的数据库条目,因此问题空间是分布式系统的可能性非常不太可能。问题不在于生成唯一的 ID,本质上,它选择了一种方案,可以最大限度地减少口语时的错误并且不允许枚举。一个例子是网站上的新闻项目,它们可能有一个内部 ID,但会泄露有关未发布项目的信息。从根本上说,问题在于这个问题是模棱两可的。
【解决方案5】:

这是一个基于 uuid 的示例。调整 1000000 以增加或减少您的 id 的范围。由于您正在缩小 id 的范围,因此您可能需要检查该 ID 是否已经存在。

>>> import uuid
>>> hash(str(uuid.uuid1())) % 1000000
380539
>>> hash(str(uuid.uuid1())) % 1000000
411563

【讨论】:

  • 随机性与唯一性无关。
  • 使用随机数完全等同于使用大小相等的散列,如果您以后不需要为同一个对象再次复制相同的 ID。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-11
  • 1970-01-01
  • 2010-11-15
  • 2015-09-25
  • 2011-07-15
  • 2018-05-04
相关资源
最近更新 更多