短URL系统的原理及其实现
浏览:117 时间:2024-6-8

背景

  提供一个短址服务

您是否发现在我们的任务中使用长URL非常麻烦?如果有一个短期发电机,那就没问题了。虽然市场上有很多,但我们可以重新发明轮子并利用这个机会尝试简单的Web全栈开发。

 任务

创建一个短链接生成器,可以缩短到短链接的长链接。

 要发车了 :bus:

在你开始之前,让我谈谈它

如果你不想制作一个轮子并且想要开箱即用,你可以使用基于PHP的开源软件YOURLS。 YOURLS还可以与WordPress集成,后者功能强大且可扩展。

本文介绍了开发短URL系统的整个过程,包括初始算法研究,模块设计,数据库设计和功能扩展。

 什么是短链接 :link:

是将普通的URL转换为更短的URL。例如:http://t.cn/RlB2PdD这是微博中这些有限字数的应用。好处是不言而喻的。简短,人物少,美观,易于发布,传播。

百度短网址http://dwz.cn/

谷歌短URL服务https://goo.gl/(需要科学上网)据称是最快的:火箭:

 原理解析

当我们在浏览器中输入http://t.cn/RlB2PdD时

DNS首先解析http://t.cn的IP地址

当DNS获取IP地址(例如:74.125.225.72)时,它将向该地址发送HTTP GET请求以查询短代码RlB2PdD

http://t.cn服务器将通过短代码RlB2PdD

获取相应的长URL

该请求通过HTTP 301转发到相应的长URLhttps://m.helijia.com。

这里有一个小知识点。为什么使用301而不是302?

301是永久重定向,302是临时重定向。生成短地址后,它将不会更改,因此使用301与http语义一致。同时,服务器压力会有一定程度的降低。

但是如果我们使用301,我们就无法计算点击短地址的次数。这次点击是大数据分析的一个非常有趣的来源。有很多东西可以分析。所以选择302将增加服务器压力,但我认为这是一个更好的选择。

从答案到iammutex

  算法实现

Internet上有两种自动递增算法和摘要算法。

 算法一

自递增序列算法也称为永不重复算法

设置id增量,十进制id对应十六进制值,1到1,不会有重复。这利用了当低阶转换为高阶二进制时字符数减少的特征。

如下图所示:十进制10000,对应于不同基数的字符表示。

短地址的长度一般设置为6位,每个位由[a - z,A - Z,0 - 9]组成,共62个字母,所以如果有6位,则总共有62 ^ 6~=568亿组合基本上就足够了。

哈哈,这是一个二进制转换工具http://tool.lu/hexconvert/上图中的数据是用这个工具生成的。

具体算法由Google实施。

  算法二

从长URL md5生成一个32位签名字符串,分为4个段,每个段8个字节。

对于四阶段循环处理,取8个字节并将其视为带有0x3fffffff(30 bit 1)的十六进制字符串和操作,即超过30位的忽略处理

这30位被分成6个段,每个5位用作字母的索引以获得特定字符,然后依次获得6位字符串

总md5字符串可以获得4个6位字符串,其中任何一个都可以用作此长URL的短URL地址

该算法虽然生成4,但仍有重复的可能性

  两种算法对比

第一种算法具有易于理解且从不重复的优点。然而,短代码的长度不固定,并且随着id变大而从一位长度增加。如果要固定短代码长度,可以只增加指定数字的id。此算法由百度短网址使用。上述开源短URL项目YOURLS也使用该算法。来源学习

第二种算法,虽然概率很小,但存在碰撞(重复)的可能性。短代码号是相对固定的。不会从一个长度增加到多个数字。该算法据说由微博使用。

我正在使用算法之一。一个不太好的事情是出现的短代码是有序的,可能是不安全的。我的方法是不按顺序构造十六进制字母。因为我想实现自定义短代码的功能,所以我对算法进行了优化,将在下面介绍。

 流程图

  自增序列算法流程图

St=>开始:开始

e=>结束:结束

Io1=> inputoutput:输入网址

Io2=> inputoutput:返回一个短网址

Op1=>操作:返回相应的短代码

Op2=>操作:将输入的URL保存到数据库

Op3=>操作:根据id

计算相应的短代码

Op4=>操作:将短代码更新到数据库

Cond1=>条件:查询数据库

有没有一对

短代码应该是

ST-> io1-> COND1

COND1(无,底部) - > OP2-> op3-> op4-> OP1-> io2->,E

COND1(是) - > OP1-> io2->,E

 自增序列算法 + 用户自定义短码 流程图

St=>开始:开始

e=>结束:结束

Io1=> inputoutput:输入网址

Io2=> inputoutput:返回一个短网址

Io3=> inputoutput:提示用户

这个短代码已经存在

Io4=> inputoutput:提示用户

无法输入短链接

Op1=>操作:返回短代码

Op2=>操作:将输入的URL保存到数据库

Op3=>操作:根据id

计算相应的短代码

Op4=>操作:查询数据库

得到一个

自定义短代码网址

相应的身份记录

Op5=>操作:将短代码更新到数据库

Cond1=>条件:查询数据库

URL是否存在

Cond2=>条件:用户选择

自定义短代码

Cond3=>条件:生成短代码

是否存在

Cond4=>条件:短代码是否存在

Cond5=>条件:短代码是否存在

Cond6=>条件:自定义短代码

是否存在

Cond7=>条件:用户输入了短链接

ST-> io1-> cond7

Cond7(无,底部) - > COND1

Cond7(是) - > io4->,E

COND1(无,底部) - > COND2

COND1(是) - > OP1-> io2->,E

COND2(无,底部) - > op3-> COND4

COND2(是) - > cond5

Cond4(不,底部) - > op5-> op1-> io2-> e

COND4(是) - > op4-> op3-> COND4

Cond5(无,底部) - > OP5

Cond5(是) - > IO3->,E

百度短网址还允许用户自定义短代码,算法两种汇总算法,不与id绑定,似乎很好地实现了这个功能。

但是,自增量序列算法绑定到id。如果允许自定义短代码,则短代码将被占用。生成id后,使用了短代码,并且id递增。不冲突的优势无法体现。

 那么怎么实现自定义短码呐?

  我是这样处理的:

数据库添加类型类型字段以标记短代码是由用户生成还是由系统自动生成。

如果存在用户定义的短代码,请自定义其类型标记。每次基于id计算短代码时,如果发现相应的短代码被占用,则从类型定制记录中选择记录,并且通过其id来计算其短代码。

这可以区分由用户定义或由系统自动生成的长连接,也不会浪费自定义短代码占用的ID。

我保留了一个1到2位的短代码,从一个三位数的短代码开始。就像保留域名的域名一样,最好保留: smirk:

 数据表设计

  links 表

 后期功能扩展

统计:点击,访问的IP区域,用户使用的设备

管理背景:删除,数据量

登录:权利管理

设置密码:输入密码以继续访问