Php 如何创建独特的ID,如YouTube?
我一直想知道他们是如何以及为什么这样做的……例如: 这些ID是如何生成的,这样就不会有重复的ID,与简单的自动递增数字ID相比,它有什么优势Php 如何创建独特的ID,如YouTube?,php,database,Php,Database,我一直想知道他们是如何以及为什么这样做的……例如: 这些ID是如何生成的,这样就不会有重复的ID,与简单的自动递增数字ID相比,它有什么优势 如何保持它的简短,但仍然保持它的独特性?uniqid创建的字符串相当长。自动递增可以很容易地进行爬网。这些无法预测,因此无法按顺序爬网 我建议使用双url格式(类似于SO url): 如果您需要url中的id和标题,那么可以使用简单的数字,如0001、0002、0003等 生成这些密钥非常简单。您可以使用PHP中的函数生成13个字符,或23个具有更大熵的字
如何保持它的简短,但仍然保持它的独特性?uniqid创建的字符串相当长。自动递增可以很容易地进行爬网。这些无法预测,因此无法按顺序爬网 我建议使用双url格式(类似于SO url): 如果您需要url中的id和标题,那么可以使用简单的数字,如0001、0002、0003等
生成这些密钥非常简单。您可以使用PHP中的函数生成13个字符,或23个具有更大熵的字符。一种方法是使用每次都具有唯一输入的哈希函数 示例(您已经用php therfore标记了问题):
应该有一个PHP库来生成这些ID。如果没有,实施起来并不困难
这样做的好处是,以后在尝试重新组织或合并不同的服务器资源时,不会出现名称冲突。对于数字ID,您必须更改其中一些以解决冲突,这将导致Url更改导致SEO命中。这在很大程度上取决于您需要做什么。“独特”是如何独特的?您是否提供了唯一ID,它们在您的DB中是否有意义?如果是这样的话,一个连续的#就可以了 另一方面,如果你使用sequential#,有人会通过迭代数字系统地窃取你的内容 有一些文件系统命令将生成唯一的文件名,您可以使用这些命令 或GUID。尝试以下操作: uniqid-生成唯一ID 基于当前时间(以微秒为单位)获取带前缀的唯一标识符 小心 此函数不生成加密安全值,不应用于加密目的。如果需要加密的安全值,请考虑使用,或者改为“< /P>”。 警告 此函数不保证返回值的唯一性。由于大多数系统通过NTP或类似方式调整系统时钟,因此系统时间不断变化。因此,此函数可能不会返回进程/线程的唯一ID。使用
更多的熵来增加唯一性的可能性
我没有公式,但我们是在我参与的一个项目上做的。(我不能分享)。但我们基本上是一次生成一个字符并附加字符串
一旦我们有了一个完整的字符串,我们就会对照数据库检查它。如果没有其他选择,我们就选择它。如果是重复的,我们重新开始这个过程。不太复杂
优点是,我想这是一个好主意 考虑使用类似于:
$id=base64_编码(md5(uniqid(),true))
uniqid将为您获取唯一标识符。MD5将对其进行扩散,得到128位的结果。Base64编码,在一个适合在web上使用的标识符中,每个字符可以有6位,大约有23个字符,计算起来很难猜测。如果你想变得更加偏执,从md5升级到sha1或更高。像SHA-1或md5这样的散列函数和GUID的结果往往会变得非常长,这可能是你不想要的。(您特别提到了YouTube作为一个例子:即使他们正在托管大量视频,他们的标识符也相对较短。)
这就是为什么在将数字ID放入URL时,您可能希望将您在后台使用的数字ID转换为另一个基。例如,Flickr使用Base58作为其规范的短URL。有关此操作的详细信息,请访问:。如果您正在寻找通用的解决方案,请查看PEAR包Mathe_Basex
请注意,即使在另一个基中,也可以从应用程序外部预测ID。如果您想要短URL,并且不需要考虑可预测性,则可以。base62或base64对主键的值进行编码,然后将其存储在另一个字段中
主键12443=3eH的示例base62
节省了一些空间,这就是为什么我确信youtube正在使用它
在PK或唯一标识符上进行base62(a-Za-z0-9)编码将避免检查密钥是否已存在的开销:)凯文·范·佐内维尔德(Kevin van Zonneveld)编写了一个优秀的PHP函数来实现这一点。他的方法是我在研究这个话题时发现的最好的方法
他的功能相当巧妙。它使用固定的$index变量,因此可以删除有问题的字符(例如元音,或避免O和0混淆)。它还提供了一个模糊id的选项,以便它们不容易被猜测。我也有一个类似的问题-我在数据库中有主id,但我不想向用户公开它们-最好显示某种哈希。所以,我写了hashids
文件:
来源:
使用此类创建的哈希是唯一的且可解密的。您可以提供一个自定义的salt值,这样其他人就无法解密您的哈希(这不是一个大问题,但仍然是一个“很好的选择”)
要加密数字,请执行以下操作:
require('lib/Hashids/Hashids.php');
$hashids = new Hashids\Hashids('this is my salt');
$hash = $hashids->encrypt(123);
您的$hash
现在将是:YDx
您还可以将最小哈希长度设置为构造函数的第二个参数,以便哈希长度更长。或者,如果您有一个复杂的集群系统,您甚至可以将多个数字加密为一个哈希:
$hash = $hashids->encrypt(2, 456); /* aXupK */
(例如,如果集群2中有一个用户和一个主id为456的对象),则解密的工作方式相同:
$numbers = $hashids->decrypt('aXupK');
$numbers
将是:[2456]
这样做的好处是,您甚至不必将这些散列存储在数据库中。你可以
$hash = $hashids->encrypt(2, 456); /* aXupK */
$numbers = $hashids->decrypt('aXupK');
9 007 199 254 740 992 unique id's
var UID={
ix:'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
enc:function(N){
N<=9007199254740992||(alert('OMG no more uid\'s'));
var M=Math,F=M.floor,L=M.log,P=M.pow,r='',I=UID.ix,l=I.length,i;
for(i=F(L(N)/L(l));i>=0;i--){
r+=I.substr((F(N/P(l,i))%l),1)
};
return UID.rev(new Array(10-r.length).join('a')+r)
},
dec:function(S){
var S=UID.rev(S),r=0,i,l=S.length,I=UID.ix,j=I.length,P=Math.pow;
for(i=0;i<=(l-1);i++){r+=I.indexOf(S.substr(i,1))*P(j,(l-1-i))};
return r
},
rev:function(a){return a.split('').reverse().join('')}
};
var uniqueId=UID.enc(9007199254740992);
var id=UID.dec(uniqueId);
console.log(UID.enc(9007199254740992))//9 biliardi o 9 milioni di miliardi
console.log(UID.enc(1)) //baaaaaaaa
console.log(UID.enc(10)) //kaaaaaaaa
console.log(UID.enc(100)) //Cbaaaaaaa
console.log(UID.enc(1000)) //iqaaaaaaa
console.log(UID.enc(10000)) //sBcaaaaaa
console.log(UID.enc(100000)) //Ua0aaaaaa
console.log(UID.enc(1000000)) //cjmeaaaaa
console.log(UID.enc(10000000)) //u2XFaaaaa
console.log(UID.enc(100000000)) //o9ALgaaaa
console.log(UID.enc(1000000000)) //qGTFfbaaa
console.log(UID.enc(10000000000)) //AOYKUkaaa
console.log(UID.enc(100000000000)) //OjO9jLbaa
console.log(UID.enc(1000000000000)) //eAfM7Braa
console.log(UID.enc(10000000000000)) //EOTK1dQca
console.log(UID.enc(100000000000000)) //2ka938y2a
function uniqueKey($limit = 10) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randstring = '';
for ($i = 0; $i < $limit; $i++) {
$randstring .= $characters[rand(0, strlen($characters))];
}
return $randstring;
}