QQ泡沫乐园 · 免费提供游戏辅助,破解软件,活动资讯,喜欢记得收藏哦!
综合软件_线报活动_游戏辅助_最新电影_最优质的的辅助分享平台

如何将短链接还原成之前的长网址转换为较短的网址

网络 2023-02-02 05:59

前言

事情是这样的,今天一人问我一个问题,但是我懒得在说,就在网上找了一篇博客通过QQ发送给他,但是在发送链接时我发觉之前很长的链接弄成了短链接,且这个短链接才能正常访问之前的长链接,好奇之下就有了这篇文章.

什么是短链接?

什么是短链接?

我的理解就是通过一定的算法和技术实现将本来很长的网址转换为较短的网址,从而易于用户记忆和在互联网上的传播.常用于有字数约束的微博,二维码等场景.

现在好多公司都提供了短链接服务,比如百度,新浪微博等等,以供用户自由便捷的生成短链接.

短链接的大致整体流程

今天上午我找的原先链接是这个:

https://blog.wpjam.com/m/scripts-and-plugins-for-analyzing-website-traffic-stats/

生成的短链接(长期的话可能会无效):

可以统计的短链接_长链接转换短链接原理_淘宝长链接短链接区别

http://url.cn/5r8GoSZ

大致流程是这样的:我复制(输入)了一个长链接,通过腾讯服务器的转化后得到一个以开头的短链接,然后我可以将该网址在互联网上进行分享和传播,其他人在访问该短网址可以步入到之前本来长网址对应的页面.

注意问题

所以要想将生成短链接,我们须要注意两个问题:

1. 如何将任意长的字符串转化为较短长或则固定长的字符串.

2. 如何将短链接还原成之前的长链接,使之才能访问.

Hash实现

通过一定形式将任意长的文本转化为一个固定长的字符串,只要目标文本宽度适当,那么我们对于不同的输入通过哈希几乎(注意是几乎)不可能得到对应同一个字符串.通过对长链接进行Hash运算,将Hash值作为这个长链接的惟一标识.但是通过Hash实现可能会导致碰撞.不一样的长网址减短成了同一个短网址,那也就做不到复原了.

对于碰撞问题,有一种缓冲方式就是在呈现碰撞了之后上面在降低随机字符,随机字符的降低才能减轻碰撞的疑惑,但是这终究是一种缓冲的办法,没有彻底解决碰撞.

自增序列算法

淘宝长链接短链接区别_可以统计的短链接_长链接转换短链接原理

自增序列算法(永不重复算法)

我们可以设置一个自增id,对于每一个新的长链接给他一个不重复的id.

原理:当服务器接收到一个网址时首先检验这个网址在服务器中是否再存,如果不存在,存储这个新网址并分发一个id,这个id设置成自增,保证了每一个储存的网址的id都是惟一标识.比如前面的,当一个链接过来时,给这个链接发一个0,再有一个链接过来时,给前面这个链接一个1,以此类推.

数据实现:我们发觉短链接旁边的参数似乎都是定长的,但是假如通过id进行时,参数不定长,且随着id的自增,可能会出现此类情况:url.cn/10000000.我们可以将十进制的id转化为多补码,比如在以'0-9a-z'这36个字符表示的36补码中,一亿可以被表示为1njchs,基本实现不重复够用.如果数据量更大,我们可以采用62进制进行转化:

短址的厚度通常设为 6 位,而每一位是由 [a - z, A - Z, 0 - 9] 总共 62 个字母组成的,所以 6 位的话,总共会有 62^6 ~= 568亿种组合。

存储实现

对于大型系统,简单的mysql系统的表自增索引即可实现(注意自增id数据类型,int只能到65535)

大型系统可以搭建分布式key-value系统进行储存.

我使用mysql简单建了一张表,用于保存长网址的数据,只有两个数组,一个是字段用于保存id,一个url数组用于储存原始的长网址.在进行长网址转换时,先检测数据表中是否存在该长网址,如果存在直接获取该记录的id,否在创建一条新的记录并返回该记录的id,对于这id进行补码转化处理后拼接到打算好的域名前面得到一个对应的短网址返回给用户.

这里我简单模仿了一个转换短链接的功能:

长链接转换短链接原理_淘宝长链接短链接区别_可以统计的短链接

url.php:用于模拟数据库储存

 return array(    'http://test1.com/12345vn6',    'http://test2.com/1234gf56',    'http://teat1.com/123ssgg456',    'http://test1.com/1234svss56',    'http://tefasfd1.com/123456',    'http://tesddt1.com/12sss3456',    'http://tehghdgst1.com/123dsaf456',    'http://tedddst1.com/12SDsd3456',    'http://testaa1bb.com/1234ccgfryh56',    'http://testaa1dfd.com/1234ccgfryh56',    'http://testaa1.com/1234ccgfryh56',    'http://testaa1.cssom/1234ccgfryh56',    'http://testaa1.com/1234ccgfryh56',    'http://testraa1.com/1234ccgfryzh56',    'http://teffstaa1.com/1234ccgfsryh56',    'http://testaxxa1.com/1234ccgfrsryh56',    'http://testaa1ll.com/1234ccgyrfryh56',    'http://testaa1.com/1234ccgfryyh56',    'http://tesbbtaa1.com/1ss234cjcgfryh56',) ?>

get.php:用于模拟生成短链接

    require './jinzhi.php';    $arr = include('./url.php');     $host = 'http://url.cn/';     $url = $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'];     $keyId = in_array($url, $arr) ? array_search($url, $arr) : (array_push($arr, $url) - 1);     $toKey = get_char($keyId);     echo $host . $toKey; ?>

jinzhi.php:模拟补码转化

 /** * @desc  im:十进制数转换成三十六机制数 * @param (int)$num 十进制数 * return 返回:三十六进制数*/function get_char($num) {    $num = intval($num);    if ($num <= 0)        return false;    $charArr = array("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');    $char = '';    do {        $key = ($num - 1) % 36;        $char= $charArr[$key] . $char;        $num = floor(($num - $key) / 36);    } while ($num > 0);    return $char;}/** * @desc  im:三十六进制数转换成十机制数 * @param (string)$char 三十六进制数 * return 返回:十进制数 */function get_num($char){  $array=array("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");  $len=strlen($char);  for($i=0;$i<$len;$i++){    $index=array_search($char[$i],$array);    $sum+=($index+1)*pow(36,$len-$i-1);  }  return $sum;}
?>

进行路由恳求::4000/get.php/10000000

输出:

至于解析短链接跳转至原有链接,只是对前面思路进行取反.

摘要算法

实现思路:

将长网址 md5 生成 32 位签名串,分为 4 段, 每段 8 个字节

对这四段循环处理, 取 8 个字节, 将他看成 16 进制串与 0x3fffffff(30位1) 与操作, 即超过 30 位的忽视处理

这 30 位分成 6 段, 每 5 位的数字作为字母表的索引取得特定字符, 依次进行获得 6 位字符串

总的 md5 串可以获得 4 个 6 位串,取上面的任意一个就可作为这个长 url 的短 url 地址

这种算法其实会生成四个短链接,但是存在重复机率.

算法对比

1.采用自增序列的益处就是简单好理解易操作.但是因为id随着减小厚度不固定,但是这个问题可以通过让id从指定的数字开始递增即可以解决.还有一个问题就是我们使用的短码是有序的,可能会存在安全方面的问题.当然相关的防护手法也有好多,比如签名验证之类的安全策略;我们也可以自己实现安全手法,比如从一个随机中心值进行开端计数,然后选用一些校检位算法估算出固定位的校检码,将其联接上去,得到固定长不递增的短码.

2.第二种算法存在碰撞的问题,虽然形成重复(碰撞)的概率很小.但是也采用这些算法也有一个用处就是短码的位数是固定的,不会从一位到多位.

所以这两种算法各有千秋,如果事务所须要的短链接有效期较短,那么通过批处理定期清洗,那么用摘要算法也不错.而自增算法才能确保任何请求量都不会呈现冲突也不失一种非常好的解决算法.

重定向的问题(301还是302)

短链接重定向的执行过程:

长链接转换短链接原理_淘宝长链接短链接区别_可以统计的短链接

用户访问短链接:

短链接服务器dwz.cn收到恳求,根据URL路径9WnR9Qcx获取到原始的长链接:

服务器返回状态码,将响应头中的Location设置为:

浏览器重新向发送恳求

返回响应

Request URL: https://dwz.cn/9WnR9QcxRequest Method: GETStatus Code: 302 FoundRemote Address: 220.181.164.108:443Referrer Policy: no-referrer-when-downgrade Access-Control-Allow-Credentials: trueAccess-Control-Allow-Headers: Origin,Accept,Content-Type,X-Requested-WithAccess-Control-Allow-Methods: POST,GET,PUT,PATCH,DELETE,HEADAccess-Control-Allow-Origin: Content-Length: 47Content-Type: text/html; charset=utf-8Date: Wed, 03 Oct 2018 05:42:18 GMTLocation: http://www.lishanlei.cn/

那么服务器在返回状态码时应当选定301还是302呢?

301是永久重定向,而302是临时重定向.

如果选定301,短链接生成之后就不会变化,所以用301符合http语义,这样对服务器的压力会有所降低.但是这样一来,我们就没法统计短地址被点击的次数了.

而选择302会降低服务器的压力,但是我们可以统计短链接被点击的次数,这些数据可能对于公司的发展规划十分重要.

综上所述,我觉得更好的应当选择302

End