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

什么是短链接?

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

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

短链接的大致整体流程

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

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

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

http://url.cn/5r8GoSZ

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

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

  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:用于模拟数据库存储

<?phpreturn 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:用于模拟生成短链接

<?phprequire './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:模拟进制转化

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

进行路由请求:http://localhost:4000/get.php/10000000

输出:http://url.cn/J

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

摘要算法

实现思路:

  1. 将长网址 md5 生成 32 位签名串,分为 4 段, 每段 8 个字节
  2. 对这四段循环处理, 取 8 个字节, 将他看成 16 进制串与 0x3fffffff(30位1) 与操作, 即超过 30 位的忽略处理
  3. 这 30 位分成 6 段, 每 5 位的数字作为字母表的索引取得特定字符, 依次进行获得 6 位字符串
  4. 总的 md5 串可以获得 4 个 6 位串,取里面的任意一个就可作为这个长 url 的短 url 地址

这种算法虽然会生成四个短链接,但是存在重复几率.

算法对比

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

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

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

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

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

  1. 用户访问短链接:https://dwz.cn/9WnR9Qcx
  2. 短链接服务器dwz.cn收到请求,根据URL路径9WnR9Qcx获取到原始的长链接:http://www.lishanlei.cn/
  3. 服务器返回状态码,将响应头中的Location设置为:http://www.lishanlei.cn/
  4. 浏览器重新向http://www.lishanlei.cn/发送请求
  5. 返回响应
Request URL: https://dwz.cn/9WnR9Qcx
Request Method: GET
Status Code: 302 Found
Remote Address: 220.181.164.108:443
Referrer Policy: no-referrer-when-downgradeAccess-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Origin,Accept,Content-Type,X-Requested-With
Access-Control-Allow-Methods: POST,GET,PUT,PATCH,DELETE,HEAD
Access-Control-Allow-Origin:
Content-Length: 47
Content-Type: text/html; charset=utf-8
Date: Wed, 03 Oct 2018 05:42:18 GMT
Location: http://www.lishanlei.cn/

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

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

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

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

综上所述,我认为更好的应该选择302

End

网页短链接实现原理探究相关推荐

  1. 网页短链接的实现原理

    网页短链接是指将原本较长的网址转化成较短的网址,从而便于用户的记忆与社交软件上的传播.很多互联网公司都提供了生成短链接的服务,比如新浪微博短网址服务等,本文就来聊聊实现短链接服务的基本原理. 我们不妨 ...

  2. Java 网址短链接服务原理及解决方案

    Java 网址短链接服务原理及解决方案 参考文章: (1)Java 网址短链接服务原理及解决方案 (2)https://www.cnblogs.com/xuzhujack/p/11202364.htm ...

  3. java 短链接url_Java 网址短链接服务原理及解决方案

    一.背景 现在在各种圈的产品各种推广地址,由于URL地址过长,不美观.不方便收藏.发布.传播以及各种发文字数限制等问题,微信.微博都在使用短链接技术.最近由于使用的三方的生成.解析短链接服务开始限制使 ...

  4. java短链接_Java 网址短链接服务原理及解决方案

    一.背景 现在在各种圈的产品各种推广地址,由于URL地址过长,不美观.不方便收藏.发布.传播以及各种发文字数限制等问题,微信.微博都在使用短链接技术.最近由于使用的三方的生成.解析短链接服务开始限制使 ...

  5. 长链接转成短链接的原理和实现详解

    一.为什么要设计短链接,短链接有什么好处? 1.链接变短,在对内容长度有限制的平台发文,可编辑的文字就变多了. 比如:微博,限定了只能发 140 个字,如果一串长链直接怼上去,其他可编辑的内容就所剩无 ...

  6. 最近学到的「短链接」知识

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 最近接了一个需求,涉及到了短链接的相关的知识,于是去 ...

  7. Redis数据结构Hash应用场景-存储商品、购物车、淘宝短链接、分布式Session、用户注册、发微博功能

    Hash应用场景 Hash Hash应用场景 redis存储java对象常用String,那为什么还要用hash来存储? SpringBoot+redis+hash存储商品数据 短链接 场景1:淘宝短 ...

  8. 长URL链接转短链接算法

    引言 很多大型网站都加入了短链接的功能.之所以要是使用短链接,主要是因为微博只允许发140 字,如果链接地址太长的话,那么发送的字数将大大减少.短链接的主要职责就是把原始链接很长的地址压缩成只有6 个 ...

  9. 16、Redis案例实战:短链接设计和案例编码

    案例实战:B站视频.淘宝购物分享短链接推广 1.需求分析 真实生产案例: B站视频推广短链接 小米购物推广短链接 淘宝购物推广短链接 好处: 简单方便,利与推广 http传输好了很多,有助于带宽节约和 ...

  10. Redis数据结构Hash实战之淘宝短链接

    网址链接过长给用户不好的体验,缩短链接长度方便社交化传播,还能跟踪点击量和统计. 算法解析 生成a~z A~z 0~9的字符,后面有用 public static void main(String[] ...

最新文章

  1. 通过IDoc来实现公司间STO场景中外向交货单过账后自动触发内向交货单的功能 – Part 2
  2. 计算机应用软件安装教程,计算机应用与网基础教程 常用软件安装.ppt
  3. Python 处理 CSV/EXCEL 表格文件
  4. 内网部署GPS定位系统方案
  5. Android 大漠插件功能,猩猩助手安卓模拟器怎么用大漠插件
  6. C语言图形库——easyx的使用
  7. 激光雷达点云之基础扫盲
  8. RS-485通讯协议
  9. python是一门胶水语言_python为何被称之为胶水语言
  10. 计算机关闭系统默认共享,win10如何关闭默认共享_win10关闭默认共享的图文步骤...
  11. cubieboard刷机
  12. Python批量检测域名是否被注册
  13. 5 位改变世界的女性程序员
  14. Android 优秀的开源库
  15. python3 接入IOS推送apn
  16. 《挑战程序设计竞赛》 读后感(转载)
  17. .设计一个Student类,该类中包括学生的姓名和成绩。创建Student类的5个对象,如下所示: 姓名 成绩 刘德华 85 张学友 100 刘杰 65 章子怡 58 周迅 76 将以上5个对象
  18. 工程经济—成本与费用
  19. Javascript——下载功能,获取电脑桌面制定下载路径
  20. 关于网站自定义字体css加密篇

热门文章

  1. 荣耀4a android art,荣耀4A拆机图解·看真相
  2. phalcon mysql_Phalcon 数据库操作总结
  3. Python中randn()函数的作用
  4. 利用黎曼几何分析EEG信号(四):集论初步与拓扑空间初步
  5. 26367411153598389kygoq
  6. 2014微软校园招聘笔试试题(英文)
  7. 网址缩短 php 安装包,PHP长链接网址缩短防封短网址短链接生成平台整站源码(一键安装)...
  8. Centos7 切换为163 网易yum
  9. 2022年最好用的5款固定资产系统
  10. 大觉寺到鹫峰线路_大觉寺-萝卜地北尖-鹫峰徒步线路攻略--登山备查