【问题标题】:Python - Why use anything other than uuid4() for unique strings?Python - 为什么使用 uuid4() 以外的任何东西来获取唯一字符串?
【发布时间】:2010-03-12 18:35:41
【问题描述】:

我看到一些针对上传图像名称、会话 ID 等内容的唯一字符串生成实现退出,其中许多使用 SHA1 等哈希值或其他方法。

我并不是在质疑使用此类自定义方法的合法性,而只是质疑其原因。如果我想要一个唯一的字符串,我就这么说:

>>> import uuid
>>> uuid.uuid4()
UUID('07033084-5cfd-4812-90a4-e4d24ffb6e3d')

我已经完成了。在阅读 uuid 之前,我并不是很信任,所以我这样做了:

>>> import uuid
>>> s = set()
>>> for i in range(5000000):  # That's 5 million!
>>>     s.add(str(uuid.uuid4()))
...
...
>>> len(s)
5000000

没有一个中继器(考虑到赔率是 1.108e+50,我不希望现在有一个中继器,但看到它在行动中令人欣慰)。您甚至可以通过组合 2 个 uuid4()s 来制作您的字符串,从而降低一半的几率。

那么,话虽如此,人们为什么要花时间在 random() 和其他东西上以获得唯一的字符串等? uuid 是否存在重要的安全问题或其他问题?

【问题讨论】:

  • 顺便说一句,将 uuid 的长度加倍会使可能值的数量成平方,而不仅仅是加倍。

标签: python unique uuid


【解决方案1】:

使用散列来唯一标识资源允许您从对象生成“唯一”引用。例如,Git 使用 SHA 散列来生成一个唯一的散列,该散列代表单个提交的确切变更集。由于散列是确定性的,因此您每次都会为同一个文件获得相同的散列。

世界各地的两个人可以独立地对同一个 repo 进行相同的更改,Git 会知道他们进行了相同的更改。 UUID v1、v2 和 v4 不支持,因为它们与文件或文件内容无关。

【讨论】:

  • 反对! UUID 实际上可以是确定性的! UUIDv3 基于 MD5 哈希,UUIDv5 基于 SHA-1 哈希。
  • 应该选择 UUIDv3 或 UUIDv5 来处理确定性的事情(上传的文件、git 变更集等),而应该选择 UUIDv1、UUIDv2 或 UUIDv4 来处理临时的、非确定性的(会话、临时文件等) )。
  • BTW git 在更改集中包含作者信息和提交日期,因此不同人的相同更改不会产生相同的哈希。不过,保存在.git 文件夹中的目标文件是一个有效的用例。
【解决方案2】:

嗯,有时你想要碰撞。如果有人两次上传完全相同的图片,也许你宁愿告诉他们这是重复的,而不是用新名称制作另一个副本。

【讨论】:

  • @Ben,你不只是将图像名称保存为行中的另一个字段,并使用编程逻辑覆盖现有图像,或者当他们再次上传相同的图像时说“哎呀”。
  • 他的观点仍然有效:有时您想要冲突,而 GUID 不提供它们。话虽如此,任何使用 SHA-1 查找 unique 字符串的人都可能做错了什么,因为它的输出几乎肯定没有输入那么独特。
  • @ladenedge 我认为 SHA1 是等式的一部分,只是为了使值更加标准化(以防有空格等)。
  • @orokusaki:根据问题的第一行,图像名称是生成的。那么这将如何帮助您识别重复项,除非它是内容的哈希值?
  • 这是我的数据库行 [image_name, image_filename, some_other_field, so_on_and_so_on]。如果我收到使用现有image_name 添加新图像的请求,我只需找到匹配的image_filename 并替换它。谁会为他们的记录系统使用实际的图像文件名?我正在开发一个多租户架构,因此可能有 5000 个客户上传了logo.jpg。我不会仅仅依赖于为每个客户端设置单独的文件夹,因为如果我将文件系统更改为一些很酷的新的类似 S3 的系统,我不想为每个客户端创建新的存储桶。这是一场噩梦。
【解决方案3】:

一个可能的原因是您希望唯一的字符串是人类可读的。 UUID 只是不容易阅读。

【讨论】:

    【解决方案4】:

    uuid 很长且无意义(例如,如果您按 uuid 排序,则会得到无意义的结果)。

    而且,因为它太长了,我不想把它放在 URL 中或以任何形状或形式向用户公开。

    【讨论】:

    • 是的,但这就是shortuuid 的用途。所有的熵,没有长度。
    【解决方案5】:

    除了其他答案之外,哈希对于应该是不可变的东西真的很有用。该名称是唯一的,可用于随时检查它所附加的任何内容的完整性。

    【讨论】:

      【解决方案6】:

      还要注意其他类型的 UUID 甚至可能是合适的。例如,如果您希望您的标识符可订购,则 UUID1 部分基于时间戳。这完全取决于您的应用程序要求...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-09
        • 2018-09-29
        • 1970-01-01
        • 2017-05-22
        • 2022-09-23
        • 1970-01-01
        • 2012-12-01
        • 1970-01-01
        相关资源
        最近更新 更多