PHP URL缩短算法

13

有人能推荐一个在PHP中用于URL缩短的首选算法吗?最初我考虑编写一个从字符“a”开始迭代请求的程序,创建数据库记录,因此必须适当地增加字符到b、c、d...A、B等。

但是我意识到这个算法可能会相当笨重/笨拙,可能有更好的方法来完成它。

我在谷歌上查阅了一些资料,有些人似乎是通过将数据库ID列进行基本转换来实现的。这不是我太熟悉的东西。

能否有人详细解释一下如何实现这个功能?也希望提供一些代码示例。

显然,我不想得到完整的解决方案,因为我想通过自己的努力学习,但只是对如何实现这个功能的解释/伪代码将非常有帮助。

7个回答

18
大多数缩短服务只是使用一个计数器,每次输入时递增,并将基数从10转换为64。
在PHP中的实现可能如下所示:
function encode($number) {
    return strtr(rtrim(base64_encode(pack('i', $number)), '='), '+/', '-_');
}
function decode($base64) {
    $number = unpack('i', base64_decode(str_pad(strtr($base64, '-_', '+/'), strlen($base64) % 4, '=')));
    return $number[1];
}

$number = mt_rand(0, PHP_INT_MAX);
var_dump(decode(encode($number)) === $number);
encode函数接收一个整数,将其转换为字节(pack),使用Base-64编码(base64_encode)对其进行编码,删除尾部填充的=rtrim),并将字符+/分别替换为-_strtr)。decode函数是encode的反函数,执行相反的操作(除了添加尾部填充)。

strtr的附加用途是将原始的Base-64字母表翻译成URL和文件名安全字母表,因为+/需要使用百分号编码进行编码。


谢谢您的建议!现在有很多东西可以让我去尝试。我将会尝试使用Base64。谢谢。 - George

5
您可以使用base_convert函数将数据库ID从10进制转换为36进制。
<?php
   $id = 315;
   echo base_convert($id, 10, 36), "\n";
?>

您可以重复使用下面页面的评论中提出的一些想法:

http://php.net/manual/zh/function.base-convert.php


2
假设您的主键是INT类型并且自动递增,以下代码将帮助您开始编写 =)。
<?php

    $inSQL = "INSERT INTO short_urls() VALUES();";
    $inResult = mysql_query($inSQL);
    $databaseID = base_convert(mysql_insert_id(), 10, 36);

    // $databaseID is now your short URL

?>

编辑:包括了HGF答案中的base_convert。我在原始帖子中忘记进行base_convert。


非常感谢。我理解了,但是如果您只使用数据库ID,您将受到数字0-9的限制,因此仅限于Base10?是否更好地利用a-zA-Z0-9?还是我刚才有点困惑了... - George

1

我曾经使用一种类似于将十进制转换为十六进制的算法来破解ID,但它使用的是62个字符,而不是十六进制使用的16个字符。

'0','1','2','3','4','5','6','7','8','9',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'

例如:如果您更改ID = 1234567890,则会得到kv7yl1作为您的密钥。


1

我采用了一种“轻量级”解决方案。用户请求时,我使用以下 Python 代码片段生成一个唯一标识符(在数据库中检查冲突):

url_hash = base64.b64encode(os.urandom(int(math.ceil(0.75*7))))[:6]

并将其存储在数据库中。


1

0

这里试试这个方法:

hash_hmac('joaat', "http://www.example.com/long/url/", "secretkey");

它将为您提供适合专业URL缩短器的哈希值,例如:'142ecd53'


从PHP7.2.0开始,禁用了非加密哈希函数(adler32、crc32、crc32b、fnv132、fnv1a32、fnv164、fnv1a64、joaat)的使用。 - maqduni

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接