我感兴趣的是创造微小的URL链接一样。我的想法是简单地存储一个递增的标识符,每长的URL发布,然后这个ID转换成它的底座36变种,像在PHP如下:

$tinyurl = base_convert($id, 10, 36)

这里的问题是,结果是可以猜测的,而它具有难以猜测下一个URL将是,同时仍然短(微小)。例如。 ATM如果我最后TinyURL的是A1,下一个会是A2。这是一个不好的事情对我来说。

那么,我将如何确保所产生的微小的网址并不像猜测的,但仍然很短?

有帮助吗?

解决方案

你所要求的是减少信息(URL到他们的索引在数据库中),和信息人工增加之间的平衡(建立在你的序列孔)。

您必须决定如何既重要的是给你的。另一个问题是,是否你只是不想连续网址是猜测的,或让他们充分随机做出猜测的任何的有效的URL困难。

基本上,要声明N个有效ID的N OUT。选择N的情况下做出的URL缩短,使n小,产生难以猜测的URL。使n和N大采取的较短的时,以产生更多的URL。

要分配的ID,你可以采取任何一种随机生成或散列函数的和如果检测到碰撞帽给你的目标范围N.,选择一个随机值。如果你已经达到了N个唯一ID的数量,必须增加您的ID组(n和N)的范围内。

其他提示

我就简单CRC32网址

$url = 'http://www.google.com';
$tinyurl = hash('crc32', $url ); // db85f073

缺点:常数8字符长标识符

这是真的很便宜,但如果用户不知道它的发生,那么它不是猜测的,但前缀和后缀实际的ID与2个或3个随机数字/字母。

如果我看到9d2a1me3我不会猜测dm2a2dq2是该系列中的下一个。

尝试用一定的价值,例如异或运算的$ ID $id ^ 46418 - 并转换回原来的ID,你只是执行相同的异或再即$mungedId ^ 46418。堆栈与base_convert了一起,也许一些结果字符串中的字符的交换,它会变得非常棘手猜测URL。

另一种方法是设置为URL的最大字符数(假设它的n)。然后,您可以选择1到n !,这将是您的排列数之间的随机数。

在这新的网址,你会增加id和使用的排列数将被实际使用的ID相关联。最后,你会基座32(或其他)编码您的网址。这将是完全随机的和完全可逆的。

如果你想要一个单射函数,则可以使用任何形式的加密。例如:

<?php
$key = "my secret";
$enc = mcrypt_ecb (MCRYPT_3DES, $key, "42", MCRYPT_ENCRYPT);
$f = unpack("H*", $enc);
$value = reset($f);
var_dump($value); //string(16) "1399e6a37a6e9870"

要反向:

$rf = pack("H*", $value);
$dec = rtrim(mcrypt_ecb (MCRYPT_3DES, $key, $rf, MCRYPT_DECRYPT), "\x00");
var_dump($dec); //string(2) "42"

这不会给你在基座32的数;它会给你的加密数据与每个字节转换为底座16(即,转换为全局的)。如果你真的需要,你可以平凡它转换为基10,然后与任何库基地32,支持大整数。

可以预先定义的4个字符码(所有可能的组合),然后随机化该列表并将其存储在数据表中的该随机顺序。当你想要一个新的价值,只要抓住第一个关闭顶部,并从列表中删除。它快速,没有上即时计算,和保证伪随机性给终端用户。

Hashids 是生成的短的,独特的,非连续的,类似YouTube的一个开源库IDS 从一个或多个数字。你可以把它看作的算法来混淆数字

它把像347号到像 “yr8”,或阵列等[27,986]变成 “3kTMd” 字符串。您也可以将这些IDS解码回来。这在捆绑几个参数为一个或简单地使用它们作为短的UID是有用的。

使用它时,您不想公开您的数据库中的 IDS 给用户。

它允许自定义的字母以及盐,所以IDS只给你独一无二的。

增量输入错位留不可猜测。

有没有冲突,因为该方法是基于整数进制转换。

这与将创建IDS在可见的地方,如URL的意图写的。因此,该算法避免了产生最常见英语脏话。

代码示例

$hashids = new Hashids();
$id = $hashids->encode(1, 2, 3); // o2fXhV
$numbers = $hashids->decode($id); // [1, 2, 3]

我结束了创建标识符的MD5和,使用第一4个字母数字的它,如果这是一个重复简单地增加长度,直到它不再重复。

function idToTinyurl($id) {
    $md5 = md5($id);
    for ($i = 4; $i < strlen($md5); $i++) {
        $possibleTinyurl = substr($md5, 0, $i);
        $res = mysql_query("SELECT id FROM tabke WHERE tinyurl='".$possibleTinyurl."' LIMIT 1");
        if (mysql_num_rows($res) == 0) return $possibleTinyurl;
    }
    return $md5;
}

接受转租的答案,因为它是导致我这一战略。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top