Unique key generation我正在寻找一种方法,特别是在PHP中,可以保证始终获得唯一的密钥。 我已经完成以下工作:
但是我发现,偶尔我会得到一个重复的密钥(很少,但是经常足够)。 我还考虑过这样做:
但是根据PHP网站,如果在同一微秒内两次调用uniqid(),则uniqid()可能会生成相同的密钥。我在想添加rand()很少,但是仍然可能。 在上述几行之后,我还将删除L和O之类的字符,因此对用户而言不那么混乱。这可能是重复的部分原因,但仍是必要的。 我想到的一个选择是创建一个网站,该网站将生成密钥,并将其存储在数据库中,以确保其完全唯一。 还有其他想法吗?是否有已经使用某种API或仅返回密钥的已经这样做的网站。我找到了http://userident.com,但不确定这些键是否完全唯一。 这需要在没有任何用户输入的情况下在后台运行。 生成唯一值的方法只有3种,它们是密码,用户ID等: 不保证任何其他方法。请记住,从根本上讲,您正在生成一个二进制数(它是一台计算机),但是您可以将其编码为十六进制,十进制,Base64或单词列表。选择适合您用法的编码。通常,对于用户输入的数据,您需要Base32的一些变体(您曾暗示过)。 关于GUIDS的注意事项:它们从其长度和生成它们的方法中获得了独特的优势。少于128位的任何内容都不安全。除了生成随机数外,GUID还具有一些特性,以使其更加独特。请记住,它们实际上几乎是唯一的,而不是完全唯一的。有可能,尽管实际上没有重复的可能。 关于GUIDS的更新注释:自撰写本文以来,我了解到许多GUID生成器都使用加密安全的随机数生成器(很难或不可能预测生成的下一个数字,并且不太可能重复)。实际上有5种不同的UUID算法。 Microsoft当前用于Windows GUID生成API的是算法4。 GUID是Microsoft对UUID标准的实现。 更新:如果需要7至16个字符,则需要使用方法2或3。 底线:坦率地说,没有完全独特的东西。即使您使用顺序生成器,您最终也将使用宇宙中的所有原子耗尽存储空间,从而循环回到自己身上并重复。您唯一的希望是在达到该点之前宇宙的热死。 即使是最好的随机数生成器,也有可能重复生成等于您生成的随机数的总大小。以四分之一为例。它是一个完全随机的位生成器,其重复几率是1比2。 因此,这一切都取决于您的独特性门槛。通过使用序列,然后对它进行base32编码,可以为1,099,511,627,776个数字的8位数字提供100%的唯一性。不涉及检查过去数字列表的任何其他方法仅具有等于n / 1,099,511,627,776(其中n =生成的先前数字的数量)的唯一性赔率。 任何算法都将导致重复。 因此,我是否建议您使用现有算法*并仅检查重复项?
*轻微的增加:如果 通常将与创建唯一值没有太大关系的加密部分进行加密,我通常使用这一部分:
在同一过程中调用$ counter时,其值将增加,因此在同一过程中值始终是唯一的。 当在不同的进程中调用时,您一定很不幸获得2个具有相同值的microtime()调用,认为在同一脚本中调用microtime()调用通常也具有不同的值。 我最近想要一个快速简单的随机唯一键,所以我做了以下工作:
因此,基本上,我得到以秒为单位的Unix时间,并添加一个由时间+随机数生成的随机md5字符串。这不是最好的,但是对于低频请求来说,这是非常好的。快速且有效。 我做了一个测试,在该测试中,我将生成数千个密钥,然后查找重复项,并且每秒大约有800个密钥,没有重复项,所以还不错。我猜这完全取决于mt_rand() 我将其用于调查跟踪器,在该跟踪器中,每分钟大约有1000项调查的提交速度...因此,现在(交叉手指)没有重复项。当然,费率不是恒定的(我们会在一天中的某些时间提交),所以这不是故障证明,也不是最佳的解决方案……提示是将增量值用作密钥的一部分(在我的情况下,我使用了time(),但可能会更好)。 我确实相信您的问题的一部分是,您正在尝试为我们提供两种单独用途的单一功能...密码和transaction_id 这些确实是两个不同的问题领域,并且最好不要一起解决它们。 我仍然看不到为什么密码必须唯一?如果您的两个用户使用相同的密码,会有什么弊端? 这是假设我们在谈论的是与用户ID关联的密码,而不仅仅是唯一的标识符。如果这就是您要寻找的,为什么不使用GUID? 正如Frank Kreuger所说,请使用GUID生成器。 像这个 您可能对史蒂夫·吉布森(Steve Gibson)的密码生成器的顶级安全实现感兴趣(无资料,但他对密码生成器的工作方式有详细说明),网址为https://www.grc.com/passwords.htm。 该站点创建了巨大的64个字符的密码,但是由于它们是完全随机的,因此您可以轻松获取前8个(或多个)字符,以获得不太安全但"尽可能随机"的密码。 编辑:从您以后的答案中,我看到您需要的像是GUID而不是密码,因此这可能不是您想要的... 我通常这样做:
我想有一些理论上的漏洞,但我从来没有遇到过重复问题。我通常将其用于临时密码(例如在重置密码后),并且足够有效。 您可能对处理同一问题的本文感兴趣:GUID在全局上是唯一的,但GUID的子字符串却不是。
|