PHP URL缩短算法

发布于 2024-09-14 18:10:53 字数 329 浏览 3 评论 0原文

谁能推荐一种用于 URL 缩短的首选算法?我正在使用 PHP 编码。最初,我考虑编写一些从“a”等字符开始并迭代请求的内容,在数据库中创建记录,因此必须将字符增加到 b、c、d ... A、B 等,合适的。

然而,我突然意识到这个算法可能相当繁重/笨拙,并且可能有更好的方法来做到这一点。

我在 Google 上阅读了一些内容,有些人似乎是通过数据库 ID 列的基本转换来实现的。这不是我太熟悉的事情。

有人可以详细说明并向我解释这是如何工作的吗?几个代码示例也很棒。

我显然不想要一个完整的解决方案,因为我想通过自己动手来学习,但只要有一个关于它如何工作的解释/伪代码就很好了。

Could anyone recommend a preferred algorithm to use for URL shortening? I'm coding using PHP. Initially I thought about writing something that would start at a character such as "a" and iterate through requests, creating records in a database and therefore having to increment the character to b, c, d ... A, B and so on as appropriate.

However it dawned on me that this algorithm could be pretty heavy/clumsy and there could be a better way to do it.

I read around a bit on Google and some people seem to be doing it with base conversion from the database's ID column. This isn't something I'm too familiar with.

Could someone elaborate and explain to me how this would work? A couple of code examples would be great, too.

I obviously don't want a complete solution as I would like to learn by doing it myself, but just an explanation/pseudo-code on how this would work would be excellent.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

梦言归人 2024-09-21 18:10:53

大多数缩短服务仅使用一个计数器,该计数器随着每个条目而递增,并将基数从 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 和文件名安全字母因为 +/ 需要使用百分比编码进行编码。

Most shortening services just use a counter that is incremented with every entry and convert the base from 10 to 64.

An implementation in PHP could look like this:

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);

The encode function takes an integer number, converts it into bytes (pack), encodes it with the Base-64 encoding (base64_encode), trims the trailing padding = (rtrim), and replaces the characters + and / by - and _ respectively (strtr). The decode function is the inverse function to encode and does the exact opposite (except adding trailing padding).

The additional use of strtr is to translate the original Base-64 alphabet to the URL and filename safe alphabet as + and / need to be encoded with the Percentage-encoding.

凉风有信 2024-09-21 18:10:53

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

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

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

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

You can use base_convert function to do a base convertion from 10 to 36 with the database IDs.

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

Or you can reuse some of the ideas presented in the comments on the page bellow:

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

风启觞 2024-09-21 18:10:53

假设您的 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 。

Assuming your PRIMARY KEY is an INT and it auto_increments, the following code will get you going =).

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

?>

EDIT: Included the base_convert from HGF's answer. I forgot to base_convert in the original post.

尴尬癌患者 2024-09-21 18:10:53

我曾经通过类似于如何从十进制转换为十六进制的算法来打破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 作为密钥。

i used to break ID by algorithm similar with how to convert from decimal to hex, but it will use 62 character instead of 16 character that hex would use.

'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'

example : if you will change ID = 1234567890 you will get kv7yl1 as your a key.

萝莉病 2024-09-21 18:10:53

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

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

并将其存储在数据库中。

I adopted a "light" solution. On user request I generate a unique identifier (checking for conflicts in db) with this python snipplet:

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

and store it in db.

遮了一弯 2024-09-21 18:10:53

本机 PHP base_convert() 适用于小范围的数字,但如果您确实需要对大值进行编码,请考虑使用类似此处提供的实现,如果您只是为编码提供更多合法字符,它将适用于 Base 64 及更高版本。

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

The native PHP base_convert() works well for small ranges of numbers, but if you really need to encode large values, consider using something like the implementation provided here which will work to base 64 and beyond if you simply provide more legal characters for the encoding.

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

表情可笑 2024-09-21 18:10:53

这里尝试这个方法:

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

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

Here try this method :

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

It will provide you with hash value fit for a professional url shortener, e.g: '142ecd53'

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文