短链接

背景

提供一个短址服务
你有没有发现,我们的任务中出现长 URL 就会比较麻烦?如果有一个短址生成器就好了。虽然市面上有很多,但是我们可以重复发明一个轮子,利用这个机会尝试一下简单的 Web 全栈开发。

任务

做一个短链接生成器,可以将一个长链接缩短成一个短链接。

预览

由 Gigalixir 提供免费部署服务,该地址只用于体验,?? 不提供数据维护存储。

体验地址

要发车了 ??

发车前,和大家说一下

如果不想重复的造轮子,想开箱即用,可以使用基于 PHP 的开源软件 YOURLSYOURLS 还可以和 WordPress 整合到一起,功能强大,可扩展性高。

本文记录了开发短网址系统的整个过程,包括初期的算法调研、模块设计、数据库设计、功能扩展等。

什么是短链接 ??

就是把普通网址,转换成比较短的网址。比如:http://t.cn/RlB2PdD 这种,在微博这些限制字数的应用里。好处不言而喻。短、字符少、美观、便于发布、传播。

百度短网址 http://dwz.cn/
谷歌短网址服务 https://goo.gl/

原理解析

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

  1. DNS首先解析获得 http://t.cn 的 IP 地址
  2. 当 DNS 获得 IP 地址以后(比如:74.125.225.72),会向这个地址发送 HTTP GET 请求,查询短码 RlB2PdD
  3. http://t.cn 服务器会通过短码 RlB2PdD 获取对应的长 URL
  4. 请求通过 HTTP 301 转到对应的长 URL https://m.helijia.com 。

这里有个小的知识点,为什么要用 301 跳转而不是 302 呐?

301 是永久重定向,302 是临时重定向。短地址一经生成就不会变化,所以用 301 是符合 http 语义的。同时对服务器压力也会有一定减少。
但是如果使用了 301,我们就无法统计到短地址被点击的次数了。而这个点击次数是一个非常有意思的大数据分析数据源。能够分析出的东西非常非常多。所以选择302虽然会增加服务器压力,但是我想是一个更好的选择。

来自知乎 iammutex 的答案

算法实现

网上比较流行的算法有两种 自增序列算法、 摘要算法

算法一

自增序列算法 也叫永不重复算法

设置 id 自增,一个 10进制 id 对应一个 62进制的数值,1对1,也就不会出现重复的情况。这个利用的就是低进制转化为高进制时,字符数会减少的特性。

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

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

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

具体的算法实现,自行谷歌。

算法二

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

这种算法,虽然会生成4个,但是仍然存在重复几率

两种算法对比

第一种算法的好处就是简单好理解,永不重复。但是短码的长度不固定,随着 id 变大从一位长度开始递增。如果非要让短码长度固定也可以就是让 id 从指定的数字开始递增就可以了。百度短网址用的这种算法。上文说的开源短网址项目 YOURLS 也是采用了这种算法。源码学习

第二种算法,存在碰撞(重复)的可能性,虽然几率很小。短码位数是比较固定的。不会从一位长度递增到多位的。据说微博使用的这种算法。

我使用的算法一。有一个不太好的地方就是出现的短码是有序的,可能会不安全。我的处理方式是构造 62进制的字母不要按顺序排列。因为想实现自定义短码的功能,我又对算法一进行了优化,下文会介绍。

流程图

自增序列算法流程图

开始输入网址查询数据库是否存在对应的短码返回对应的短码返回短网址结束保存输入的网址到数据库根据id计算对应的短码更新短码到数据库yesno

只实现长链接转化为短链接的功能,不是很麻烦。在调研的过程中我发现百度短网址可以自定义短码,我觉的这个功能挺不错,结果复杂度就是上图到下图的变化。??

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

开始输入网址用户输入的是短链接提示用户不能输入短链接结束查询数据库是否存在该URL返回短码返回短网址用户选择自定义短码短码是否存在提示用户该短码已存在更新短码到数据库根据id计算对应的短码短码是否存在查询数据库获得一条自定义短码的url对应的id记录yesnoyesnoyesnoyesnoyesno

百度短网址还允许用户自定义短码,算法二 摘要算法,不和 id 绑定,好像挺好实现这个功能的。

但是自增序列算法是和 id 绑定的,如果允许自定义短码就会占用之后的短码,之后的 id 要生成短码的时候就发现短码已经被用了,那么 id 自增一对一不冲突的优势就体现不出来了。

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

我是这样处理的:

数据库增加一个类型 type 字段,用来标记短码是用户自定义生成的,还是系统自动生成的。
如果有用户自定义过短码,把它的类型标记自定义。每次根据 id 计算短码的时候,如果发现对应的短码被占用了,就从类型为自定义的记录里选取一条记录,用它的 id 去计算短码。
这样既可以区分哪些长连接是用户自己定义还是系统自动生成的,还可以不浪费被自定义短码占用的 id

我保留了 1 到 2 位的 短码,从三位的短码开始生成的。就像域名的保留域名一样,好的要自己预留 ??

位数 个数 区间
1位 62 0 - 61
2位 3844 62 - 3843
3位 约 23万 3844 - 238327
4位 约 1400万 238328 - 14776335
5位 约 9.1亿 14776336 - 916132831
6位 约 568亿 916132832 - 56800235583

数据表设计

links 表

字段 含义
id link_id
url 长连接
keyword 短链接码
type 系统: “system” 自定义: “custom”
insert_at 插入时间
updated_at 更新时间

后期功能扩展

统计:点击量、访问的 ip 地域、用户使用的设备

管理后台:删除、数据量

登录:权限管理

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

项目源码

使用 Elixir + phoenix 技术栈 short_url

转自:https://hufangyun.com/2017/short-url/

原文地址:https://www.cnblogs.com/linguoguo/p/12287366.html

时间: 2024-10-03 12:43:08

短链接的相关文章

PHP伪静态与短链接

如今,Web服务高速发展的时代,各式各类的门户网站,如新浪http://www.sina.com.腾讯http://www.qq.com,这些网站大家都很容易记住,因为这种名称都是有规则和含义的.如果给你一个http://14.215.177.38,你肯定记不住这个网站是什么,可是我告诉你它就是百度首页. 所以,我们在开发一个网站系统的时候,还是要对链接进行优化的,而我理解的优化类型有伪静态与短连接. 其实,如果你数据结构学的不错,这个对你来说很容易理解,毕竟它就是一种地址映射的关系. 常识告诉

THINKPHP短链接设置方法(路由设置)

//路由设置(短链接设置)'URL_ROUTER_ON' => true,'URL_ROUTE_RULES' => array('log' => 'Login/index','admin' => 'Login/admin','reg' => 'Login/register', 'c/:id' => 'Index/index/user' '/^C_(\d+)$/' => 'Index/index/user?id=:1'), 长链接:http://localhost/

百度 谷歌 Twitter,这么多短链接服务(Short Url)到底哪家强?

一.短链接是什么 短链接,通俗来说,就是将长的URL网址,通过程序计算等方式,转换为简短的网址字符串. 它的原理也非常简单,就是采用 Domain Redirect(域名重定向) ,将一个域名自动跳转到另一个域名. 根据wikipedia描述,短链接的方案最早在2000年诞生.在2009年11月,著名短链接服务提供商Bitly的访问量是21亿,可见短链接的使用需求是非常大的. 维基地址 而在国内,短链接的普及与微博息息相关. 最早是由新浪仿照Twitter的140短篇博文功能,上线了新浪微博,之

微信公众号开发-长链接转短链接

主要使用场景: 开发者用于生成二维码的原链接(商品.支付二维码等)太长导致扫码速度和成功率下降,将原长链接通过此接口转成短链接再生成二维码将大大提升扫码速度和成功率. http请求方式: POST https://api.weixin.qq.com/cgi-bin/shorturl?access_token=ACCESS_TOKEN 参数说明 参数 是否必须 说明 access_token 是 调用接口凭证 action 是 此处填long2short,代表长链接转短链接 long_url 是

php 微信接口API之长链接转短链接代码示例

[php] view plain copy <?php header("Content-Type: text/html; charset=utf-8"); $longurl; if(isset($_POST['longurl'])){ $longurl = $_POST['longurl']; }else{ die("没有post值进来"); } //echo $longurl; $id = "你的AppID"; $secret = &qu

openresty && hashids&& redis 生成短链接

1. 原理 a. 从redis 获取需要表示的短链接的id( redis incr) b. hashids 编码 id c. openresty  conteent_by_lua_block 阶段显示数据 2. 安装以来的插件 a. lua hashdis  使用  luarocks 注意需要先安装lua 开发包 b. copy hashids lua 包 到 openresty 的lualib  方便调用 c. redis 安装 luarocks install hashids 3. 代码 n

java 短连接+MD5加密短链接

java 短连接+MD5加密短链接 import java.security.MessageDigest; public class ShotUrlUtil { public static void main(String[] args) { System.out.println(shortUrl("http://www.baidu.com/")); } public static String shortUrl(String url) { String[] chars = new S

新浪短链接API接口示例

<?php /** * URL地址长短切换,由sina新浪短链接API生成 * User: chenqt * Date: 2016/8/23 * Time: 18:45 */ class UrlSwitch { public function __construct() { //访问sina的key $this->sina_appkey = '31641035'; } private function curlQuery($url) { //设置附加HTTP头 $addHead = array

将一条长链接转成短链接

package com.wanhua.weixin.util; import java.util.HashMap;import java.util.Map; import org.json.JSONObject; import play.cache.Cache;import play.i18n.Messages; import com.alibaba.fastjson.JSON;import com.wanhua.weixin.model.AccessToken; /** * 请求地址url的工

java清除所有微博短链接

java实现微博短链接清除,利用正则,目前只支持微博短链接格式为"http://域名/字母或数字8位以内"的链接格式,现在基本通用 如果链接有多个,返回结果中会有多出的空格,请注意! 实现代码: 1.测试版       public static void main(String[] args) { // System.out.println(testFilter("刚在#微操盘#卖出的这支600111 包钢稀土 又挣钱了!有木有!人品爆发了有木有! http://t.cn/