我正在寻找一种方法,特别是在PHP中,我将保证始终获得一个独特的密钥.
我做了以下事情:
strtolower(substr(crypt(time()), 0, 7));
但我发现,偶尔我会得到一个重复的密钥(很少,但经常就足够了).
我也想过这样做:
strtolower(substr(crypt(uniqid(rand(), true)), 0, 7));
但是根据PHP网站,uniqid()可以,如果uniqid()在相同的微秒内被调用两次,它可以生成相同的密钥.我认为添加rand()很少会,但仍然可能.
在上面提到的行之后,我也删除了诸如L和O之类的字符,因此对用户来说不那么容易混淆.这可能是重复原因的一部分,但仍然是必要的.
我想到的一个选择是创建一个生成密钥的网站,将其存储在数据库中,确保它完全独一无二.
还有其他想法吗?是否有任何已经这样做的网站有某种API或只是返回密钥.我找到了http://userident.com,但我不确定密钥是否完全独特.
这需要在后台运行而无需任何用户输入.
只有3种方法可以生成唯一值,而不是密码,用户ID等:
使用有效的GUID生成器 - 这些生成器很长,无法收缩.如果你只使用部分你失败.
至少部分数字是从单个序列顺序产生的.您可以添加绒毛或编码,使其看起来不那么连续.优势是他们开始做空 - 缺点是他们需要单一来源.单源限制的解决方法是使用编号源,因此包括[source#] + [seq#],然后每个源都可以生成自己的序列.
通过其他方式生成它们,然后根据先前生成的值的单个历史记录检查它们.
不保证任何其他方法.请记住,从根本上说,您正在生成二进制数(它是一台计算机),但您可以使用十六进制,十进制,Base64或单词列表对其进行编码.选择适合您用途的编码.通常对于用户输入的数据,您需要一些Base32的变体(您暗示过).
关于GUIDS的注释:它们从它们的长度和用于生成它们的方法中获得了它们的独特性. 任何小于128位的东西都不安全. 除了随机数生成之外,还有一些特性可以进入GUID以使其更加独特.请记住,它们实际上是独一无二的,并非完全独特.尽管实际上不可能有重复,但这是可能的.
关于GUIDS的更新说明:自写这篇文章后,我了解到许多GUID生成器使用加密安全随机数生成器(难以或无法预测生成的下一个数字,并且不太可能重复).实际上有5种不同的UUID算法.算法4是Microsoft当前用于Windows GUID生成API的算法.一个GUID是微软实现的UUID标准.
更新:如果您需要7到16个字符,则需要使用方法2或3.
一句话:坦率地说,没有完全独特的东西.即使您使用顺序生成器,您最终也会使用宇宙中的所有原子耗尽存储空间,从而重新循环自己并重复.你唯一的希望就是在达到那个点之前宇宙的热量死亡.
即使是最好的随机数生成器也有可能重复等于您生成的随机数的总大小.以四分之一为例.它是一个完全随机的比特生成器,它的重复几率是1比2.
所以这一切都归结为你的独特性门槛.对于1,099,511,627,776个数字,您可以通过使用序列然后对其进行base32编码来获得8位数的100%唯一性.任何其他不涉及检查过去数字列表的方法的赔率等于n/1,099,511,627,776(其中n =生成的先前数字的数量)不唯一.