URL缩短算法的PHP实现
我发现响应是这个问题的一个很好的答案,但是我的问题是它在PHP中会是什么样子?这是:URL缩短算法的PHP实现,php,url,Php,Url,我发现响应是这个问题的一个很好的答案,但是我的问题是它在PHP中会是什么样子?这是: 您需要一个f(必须没有x1!=x2,这将使f(x1)=f(x2);对于每个y,您将找到一个x,以便f(x)=y)。这是必要的,这样您就可以为f(123)='abc'函数找到一个反函数g('abc')=123 我将继续您的“将数字转换为字符串”方法(但是,如果您的id是素数且大于52,您将意识到您提出的算法将失败) 如何将id转换为缩短的url: 想一想你想用的字母表。你的情况是[a-zA-Z0-9]。它包含
您需要一个
f
(必须没有x1!=x2
,这将使f(x1)=f(x2)
;对于每个y,您将找到一个x,以便f(x)=y
)。这是必要的,这样您就可以为f(123)='abc'
函数找到一个反函数g('abc')=123
我将继续您的“将数字转换为字符串”方法(但是,如果您的id
是素数且大于52,您将意识到您提出的算法将失败)
如何将id
转换为缩短的url:
- 想一想你想用的字母表。你的情况是[a-zA-Z0-9]。它包含62个字母
- 以自动生成的唯一数字键(自动递增的
)为例:例如125(十进制数字)id
- 现在您必须将125(基数10)转换为X(基数62)。这将是{2}{1}(2×62+1=125)
- 现在将符号{2}和{1}映射到您的字母表。说{0}='a',{25}='z'等等。我们将有{2}='c'和{1}='b'。所以“/cb”将是您的缩短url
abc
解析为初始的id
:
- 如果你想反其道而行之,这并不困难e9a'将被解析为“字母表中的第4、61、0个字母”={4}{61}{0},即4×62×62+61×62+0=19158。然后,您只需找到id为
19158的数据库记录即可
我喜欢这个PHP函数,它允许您自定义字母表(并删除令人困惑的0/O等)
按照URL查找反向“解码”功能。Marcel解决方案的主要问题是它使用零位作为占位符。通过在基之间转换,选择表示0的数字不可避免地不能出现在转换后的数字的前面 例如,如果使用提供的机制使用“ABCD”将以10为基数的整数转换为以4为基数的整数,则无法获得以字母“A”开头的输出,因为这表示新基数中的零,并且不会作为数字的前缀。你可能认为5是“AA”,但实际上是“BA”。无法强制该算法生成“AA”,因为这就像在十进制中写入“00”,其值与“0”相同 以下是PHP中使用整个范围的替代解决方案:
function encode($n, $alphabet = 'ABCD') {
$output = '';
if($n == 0) {
$output = $alphabet[0];
}
else {
$digits = floor(log($n, strlen($alphabet))) + 1;
for($z = 0; $z < $digits; $z++) {
$digit = $n % 4;
$output = $alphabet[$digit] . $output;
$n = floor($n / 4) - 1;
}
}
return $output;
}
function decode($code, $alphabet = 'ABCD') {
$n = 0;
$code = str_split($code);
$unit = 1;
while($letter = array_pop($code)) {
$n += (strpos($alphabet, $letter) + 1) * $unit;
$unit = $unit * strlen($alphabet);
}
return $n - 1;
}
echo encode(25); // should output "ABB"
echo decode('ABB'); // should output 25
函数编码($n,$alphabet='ABCD'){
$output='';
如果($n==0){
$output=$alphabet[0];
}
否则{
$digits=floor(log($n,strlen($alphabet)))+1;
对于($z=0;$z<$digits;$z++){
$digit=$n%4;
$output=$alphabet[$digit]。$output;
$n=楼层($n/4)-1;
}
}
返回$output;
}
函数解码($code,$alphabet='ABCD'){
$n=0;
$code=str_split($code);
$unit=1;
while($letter=array_pop($code)){
$n+=(strpos($alphabet,$letter)+1)*$unit;
$unit=$unit*strlen($alphabet);
}
返回$n-1;
}
回波编码(25);//应输出“ABB”
回声解码('ABB');//应输出25
将第二个参数更改/传递到要使用的字符列表,而不是短的4字符字典“ABCD”。对不起,我忘了。重写我的答案。
// From http://snipplr.com/view/22246/base62-encode--decode/
private function base_encode($val, $base=62, $chars='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
$str = '';
do {
$i = fmod($val, $base);
$str = $chars[$i] . $str;
$val = ($val - $i) / $base;
} while($val > 0);
return $str;
}
function encode($n, $alphabet = 'ABCD') {
$output = '';
if($n == 0) {
$output = $alphabet[0];
}
else {
$digits = floor(log($n, strlen($alphabet))) + 1;
for($z = 0; $z < $digits; $z++) {
$digit = $n % 4;
$output = $alphabet[$digit] . $output;
$n = floor($n / 4) - 1;
}
}
return $output;
}
function decode($code, $alphabet = 'ABCD') {
$n = 0;
$code = str_split($code);
$unit = 1;
while($letter = array_pop($code)) {
$n += (strpos($alphabet, $letter) + 1) * $unit;
$unit = $unit * strlen($alphabet);
}
return $n - 1;
}
echo encode(25); // should output "ABB"
echo decode('ABB'); // should output 25