PHP URL缩短算法

时间:2010-08-18 15:59:01

标签: php algorithm url url-shortener

有人建议使用首选算法来缩短网址吗?我正在使用PHP进行编码。最初我想过写一些东西,从一个字符开始,如“a”,并迭代请求,在数据库中创建记录,因此必须将字符增加到b,c,d ...... A,B等等合适的。

但是我突然意识到这个算法可能非常沉重/笨拙,而且可能有更好的方法。

我在谷歌上阅读了一些内容,有些人似乎是通过数据库的ID列进行基本转换。这不是我太熟悉的东西。

有人可以详细说明并告诉我这是如何工作的吗?一些代码示例也很棒。

我显然不想要一个完整的解决方案,因为我想通过自己的方式来学习,但只是一个关于如何工作的解释/伪代码将是非常好的。

7 个答案:

答案 0 :(得分:12)

大多数缩短服务只使用一个计数器,该计数器随每个条目递增,并将基数从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)对其进行编码,修剪尾部填充{{1 (rtrim),并分别用=+替换字符/-strtr)。 _函数是decode的反函数,并且完全相反(除了添加尾部填充)。

encode的额外用途是将original Base-64 alphabet翻译为URL and filename safe alphabetstrtr+需要使用百分比编码进行编码。

答案 1 :(得分:3)

您可以使用base_convert函数使用数据库ID执行10到36的基本转换。

<?php
   $id = 315;
   echo base_convert($id, 10, 36), "\n";
?>

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

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

答案 2 :(得分:1)

假设你的PRIMARY KEY是一个INT并且它是auto_increments,下面的代码将让你去=)。

<?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。

答案 3 :(得分: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 作为您的密钥。

答案 4 :(得分:1)

我采用了“轻”解决方案。根据用户请求,我使用此python snipplet生成一个唯一标识符(检查db中的冲突):

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

并将其存储在db中。

答案 5 :(得分:1)

本机PHP base_convert()适用于小范围的数字,但是如果你真的需要编码大值,可以考虑使用类似于此处提供的实现,如果你只是提供更多的合法字符,这些实现将基于64及更高版本用于编码。

http://af-design.com/blog/2010/08/10/working-with-big-integers-in-php/

答案 6 :(得分:1)

在这里试试这个方法:

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

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

相关问题