如何在PHP中创建高效的编码/解码唯一ID
我试图找到一种方法将数据库ID编码成一个短的如何在PHP中创建高效的编码/解码唯一ID,php,base64,unique,base32,Php,Base64,Unique,Base32,我试图找到一种方法将数据库ID编码成一个短的URL,例如,1应该变成“Ys47R”。然后我想把它从“Ys47R”解码回1,这样我就可以使用INT值运行数据库搜索。使用数据库ID时,它必须是唯一的。序列不应容易猜测,例如1=“Ys47R”,2=“Ys47S”。它应该是类似于YouTube或bitly的URL的。我已经用md5、base32、base64和`bcpow阅读了数百种不同的源代码,但结果都是空的 看起来很有希望,但一旦我添加了填充和密钥,短ID就变成了SDDDG,2变成了“SDDDH”,
URL
,例如,1应该变成“Ys47R”。然后我想把它从“Ys47R”解码回1,这样我就可以使用INT
值运行数据库搜索。使用数据库ID
时,它必须是唯一的。序列不应容易猜测,例如1=“Ys47R”,2=“Ys47S”。它应该是类似于YouTube或bitly的URL的
。我已经用md5
、base32
、base64
和`bcpow阅读了数百种不同的源代码,但结果都是空的
看起来很有希望,但一旦我添加了填充和密钥,短ID就变成了SDDDG,2变成了“SDDDH”,3变成了“SDDDI”。这不是很随机的
base32
仅使用a-b 0-9
base64
末尾有==等字符
然后我试了一下:
function getRandomString($db, $length = 7) {
$validCharacters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
$validCharNumber = strlen($validCharacters);
$result = "";
for ($i = 0; $i < $length; $i++) {
$index = mt_rand(0, $validCharNumber - 1);
$result .= $validCharacters[$index];
}
函数getRandomString($db,$length=7){
$validCharacters=“0123456789abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz”;
$validCharNumber=strlen($validCharacters);
$result=“”;
对于($i=0;$i<$length;$i++){
$index=mt_rand(0,$validCharNumber-1);
$result.=$validCharacters[$index];
}
这是可行的,但意味着我每次都必须运行数据库查询,以确保没有冲突,并且数据库中不存在冲突
是否有一种方法可以创建最短的ID
,该ID至少为4个字符,字符集为[a-z][a-z][0-9]
可以在每个数字都是唯一的数据库中使用增量唯一的ID
进行编码和解码。我无法理解使用base32
或base64
的高级技术
或者我是不是研究得太多了,有一种更简单的方法可以做到?最好是执行上面的随机字符串函数,并始终查询数据库以检查唯一性?您可以使用注释中的函数:
$initial='11111111';
$dic='0123456789ABCDefghijklmnopqrstuvxyzabCDefghijklmnopqrstuvxyz';
var_dump($converted=convBase($initial,'0123456789',$dic));
//串(4)“KCvt”
var_dump(convBase($converted,$dic,'0123456789'));
//字符串(8)“11111111”
函数convBase($numberInput、$fromBaseInput、$toBaseInput)
{
如果($fromBaseInput==$toBaseInput)返回$numberInput;
$fromBase=str_分割($FROMBASEINTPUT,1);
$toBase=str_分割($toBaseInput,1);
$number=str_split($numberInput,1);
$fromLen=strlen($fromBaseInput);
$toLen=strlen($toBaseInput);
$numberLen=strlen($numberInput);
$retval='';
如果($toBaseInput=='0123456789')
{
$retval=0;
对于($i=1;$i来说,如果需要一些对称模糊处理,那么通常就足够了
base_convert($id, 10, 36);
将返回类似1i0g
的字符串并将其转换回
在基础转换之前和之后,您可以添加:
- 要获得最小字符串长度,我建议只需将
70000
添加到$id
中,然后在接收端再减去它
- 小乘法
$id*=3
将在生成的字母数字id范围中添加一些“孔”,但不会耗尽可用的字符串空间
- 对于一些随意性的外观,有点咬动:
$id = ($id & 0xF0F0F0F) << 4
| ($id & 0x0F0F0F0) >> 4;
$id=($id&0xf0f)>4;
它用于生成模糊的ID字符串,并返回原始字符串
非常清楚:这是不任何类型的加密。它只是在连续数字之间移动数字跳跃,看起来更随意
您可能仍然不喜欢答案,但在数据库中生成随机ID是真正阻碍ID猜测的唯一方法。目的是什么?如果编码的数字不可预测,那么是的,您必须随机生成它们,检查它们是否存在,并将它们存储在表actualID
键旁边e是将URL转换为bit.ly类型的URL。因此,我可以使用$\u GET参数获取id,将其转换回原始int,这样我就可以对照数据库检查他们所引用的页面,这样我就可以提取详细信息。因此,经过大量阅读,我看到了两个选项,一个是创建和检查db,当创建大量页面时,还可以增加避免冲突,或者像其他人提到的那样,像youtube一样在运行中创建它,bitly和使用base64意味着在创建时不检查数据库,可以在运行中进行,每个数字都是唯一的,最多可达十亿。主题很清楚。但是为什么要转换页面ID?这是伪安全功能吗?这是basica基本上只是模糊处理(对于这种情况,base32只需添加一个基值来增加输出长度,再加上一些位洗牌就足够了)没错,这是假设更多的混淆,加上好看的url。一个例子是,用户将发送报告链接到客户端,因此好看的短url。同时,虽然不是机密和公共知识,但我不希望有人开始在url中键入用户或客户端的id号1,2,3,4,以查看每一个链接其他人一个接一个地工作,等等。你能用base64减去==号做洗牌位并解码回来吗?这是我发现的一个链接,虽然它提到了它,但它没有说他们是如何使用base64来创建id的,但类似的概念是使用$\u get来创建唯一的短URL。我确实看到了这个方法,那个方法让我回到了我关于短id的问题例如1。如果你看一看,如果你输入1,生成的id也是1,即使你输入11,结果也是a,所以我在这里提到的两个问题,id也不像“Ys47R”这也不是不可预测的,一切都是按顺序进行的,所以很容易猜测。@user3882771,如果您真的需要从Ys47R
开始,只需在编码前添加数字“893269206”,在解码后添加减法。谢谢您的尝试
$id = ($id & 0xF0F0F0F) << 4
| ($id & 0x0F0F0F0) >> 4;