前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何设计一个短链接系统

如何设计一个短链接系统

原创
作者头像
柯柏技术笔记
修改于 2024-01-19 09:05:19
修改于 2024-01-19 09:05:19
8050
举报
文章被收录于专栏:柯柏后端架构柯柏后端架构

前言

文章有点长,大概需要花费10分钟左右,如果你读完,设计一个短链系统,面试、实战,轻松拿捏!

短链接

短链接是一种将长URL地址转换为较短、易于记忆的链接的技术。它通过使用特定的算法或服务将长链接压缩成更短的形式,以便在限制字符长度或需要更简洁的场景下使用。

代码语言:js
AI代码解释
复制
原始网址:https://cloud.tencent.com/developer/article/2378083
短网址:http://xx.cn/dFz1S

短链使用场景

短信

电商平台发送短信给用户,短信内容带链接,产生的问题:

  1. 节约成本 导致短信内容过长,短信费用翻倍。各大短信平台短信费用计算规则,短信内容小于70个字,算一条短信,超过70个字,短信按68个字算一条。如果把长链接转换为短链接大大的节约了短信费用成本。
  2. 增加体验 短信内容带长链接,一般是营销短信。如果短信内容带这么长的链接,一般用户不会点击,误以为是垃圾短信,用户转化率偏低,失去营销的意义。同时用户体验也不友好,如果换成短链,提升用户体验,用户转化率也得到提升

内容分享

内容分享平台,比如微博平台,一条微博的信息有字数限制,使用长链接会占用大量的字数,使用短链,能节约字数,内容描述的信息更丰富

二维码

二维码的内容是一段文本,这些文本通过不同的前缀可以被手机识别为不同的数据类型

影响二维码复杂度的两个属性分别是内容长度容错率

那长链接转换为短链接内容长度大大减少,二维码的复杂度就得到降低,我们以下面对应的长链接与短链接为例进行演示:

代码语言:js
AI代码解释
复制
原始网址:https://cloud.tencent.com/developer/article/2378083
短网址:http://xx.cn/dFz1S

生成的二维码的效果如下:

看上去,明显短链生成的二维码复杂度低很多,也提升了扫码识别的性能

短链接请求流程

短网址服务的一个核心功能,就是把原始的长网址转化成短网址。除了这个功能之外,短网址服务还有另外一个必不可少的功能。那就是,当用户点击短网址的时候,短网址服务会将浏览器重定向为原始网址。这个过程是如何实现的呢?

URL重定向

上面提到了重定向,那什么是重定向呢?

重定向是指当浏览器请求一个URL时,服务器返回一个重定向指令,告诉浏览器地址已经变了,麻烦使用新的URL再重新发送新请求。这个重定向响应有一个以 3 开头的状态码 ,并且有一个 Location 头字段 表示要重定向到的位置。

浏览器接收到这个重定向之后,会立即加载 Location 中指定的 URL。通常这一过程耗时极短,用户基本注意不到这个过程。

重定向过程如下图所示:

重定向响应有一个以 3 开头的状态码,状态码如图:

满足短 URL 重定向要求的 HTTP 重定向响应码有 301 和 302 两种

301 表示永久重定向,即浏览器一旦访问过该短 URL,就将重定向的原始长 URL 缓存在本地,此后不再请求短 URL 生成器,直接根据缓存在浏览器(HTTP 客户端)的长 URL 路径进行访问。

302 表示临时重定向,每次访问短 URL 都需要访问短 URL 生成器。一般说来,使用 301 状态码可以降低服务器的负载压力,但无法统计短 URL 的使用情况,比如:pv、uv的统计,因此选择使用 302 状态码构造重定向响应

短链生成方案

通过哈希算法生成短链接

哈希算法可以将一个不管多长的字符串,转化成一个长度固定的哈希值。我们可以利用哈希算法,来生成短网址。

哈希算法有很多,我们只需要关注哈希算法的两个关键点计算速度冲突概率

能够满足这样要求的哈希算法有很多,其中比较著名并且应用广泛的一个哈希算法,那就是MurmurHash

MurmurHash 算法提供了两种长度的哈希值,一种是 32bits,一种是 128bits。为了让最终生成的短网址尽可能短,我们可以选择 32bits 的哈希值

Google Guava工具包已经实现了MurmurHash算法,直接引入使用即可:

代码语言:js
AI代码解释
复制
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>30.1-jre</version>
</dependency>

示例:

代码语言:java
AI代码解释
复制
package com.example.demo;
import com.google.common.hash.Hashing;
import java.nio.charset.Charset;
public class ShortUrl {

    public static void main(String[] args) {
        String longUrl = "https://cloud.tencent.com/developer/article/2378083";
        int hashValue = toHash(longUrl);
        System.out.println(hashValue);
    }


    /**
     * 通过MurmurHash算法把长链接转换为32bit
     * @param longUrl
     * @return
     */
    public static int toHash(String longUrl){
        int hashValue =  Hashing.murmur3_32().hashString(longUrl, Charset.defaultCharset()).asInt();
        return hashValue;
    }
}

运行结果:

代码语言:js
AI代码解释
复制
长链接:https://cloud.tencent.com/developer/article/2378083  hash值:580086598

如何让短链接更短

通过 MurmurHash 算法得到的短网址:http://xx.cn/580086598 ,还是很长,那怎么办呢?再介绍一种种算法Base62

Base62编码是由10个数字、26个大写英文字母和26个小写英文字母组成,多用于安全领域和短URL生成。

Base62 索引表:

为了让哈希值表示起来尽可能短,我们可以将通过 MurmurHash得到的 10 进制的哈希值转化成 62 进制

如何做呢?

还记得十进制转二进制的算法么,除二取余,然后倒序排列,高位补零。转62进制也类似,不断除以62取余数,然后倒序。

算法如下:

代码语言:java
AI代码解释
复制
package com.example.demo;
import com.google.common.hash.Hashing;
import java.nio.charset.Charset;
public class ShortUrl {

    private static final String BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

    public static void main(String[] args) {
        String longUrl = "https://cloud.tencent.com/developer/article/2378083";
        int hashValue = toHash(longUrl);
        String result = String.format("长链接:%s  hash值:%d",longUrl,hashValue);
        System.out.println(result);
        String base62Number = convertToBase62(hashValue);
        String shortUrl = String.format("hash值:%d  base62:%s",hashValue,base62Number);
        System.out.println(shortUrl);
    }


    /**
     * 通过MurmurHash算法把长链接转换为32bit
     * @param longUrl
     * @return
     */
    public static int toHash(String longUrl){
        int hashValue =  Hashing.murmur3_32().hashString(longUrl, Charset.defaultCharset()).asInt();
        return hashValue;
    }


    /**
     * 10进制转换为62进制
     * @param decimalNumber
     * @return
     */
    public static String convertToBase62(long decimalNumber) {
        StringBuilder sb = new StringBuilder();

        while (decimalNumber > 0) {
            int remainder = (int) (decimalNumber % 62);
            sb.insert(0, BASE62_CHARS.charAt(remainder));
            decimalNumber /= 62;
        }

        return sb.toString();
    }
}

运行结果:

代码语言:js
AI代码解释
复制
长链接:https://cloud.tencent.com/developer/article/2378083  hash值:580086598
hash值:580086598  base62:dFz1S

通过MurmurHash算法把长链 哈希取值后得到10进制的哈希值,然后10进制转换base62,经过两次变化,得到的短链为http://xx.cn/dFz1S ,已经很短了,这样是不是完美了呢?

哈希算法都要考虑一个点?哈希冲突

如何解决哈希冲突问题

哈希算法无法避免的一个问题,就是哈希冲突。尽管 MurmurHash 算法,冲突的概率非常低。但是,一旦冲突,就会导致两个原始网址被转化成同一个短网址。当用户访问短网址的时候,我们就无从判断,用户想要访问的是哪一个原始网址了。这个问题该如何解决呢?

通过转换得到的短链,用这个短链接去数据库查询,如果没有,入库并且返回给用户

通过转换得到的短链接,用这个短链接去数据库查询,如果有,相应拿到这个短链对的长链,跟当前的长链接比较,如果相等,说明这个长链接已经存在,直接返回这个短链给用户,或者提示用户,这个长链接已经存在。如果说不相等,说明hash冲突了,我们可以给原始网址拼接一串特殊字符,比如“DUPLICATED”,然后再重新计算哈希值,两次哈希计算都冲突的概率,显然是非常低的。假设出现非常极端的情况,又发生冲突了,我们可以再换一个拼接字符串,比如“OHMYGOD”,再计算哈希值。然后把计算得到的哈希值,跟原始网址拼接了特殊字符串之后的文本,一并存储在 MySQL 数据库中。当用户访问短网址的时候,短网址服务先通过短网址,在数据库中查找到对应的原始网址。如果原始网址有拼接特殊字符(这个很容易通过字符串匹配算法找到),我们就先将特殊字符去掉,然后再将不包含特殊字符的原始网址返回给浏览器。

用户体验

长链转换为短链的时候,千万要注意生成的短链有没有带关键字,比如:

3691004 这个10进制数转换为base62得到的是fuck,短链为:http://xx.cn/fuck 你这样发出去,你的用户以为是你在骂他,轻则用户投诉,你这个月的奖金没了,重则公司名誉受损,给公司造成重大损失。怎么办呢?

系统里面设置一些关键字,对生成的短链接进行匹配,如果存在在关键字里,像上面一样拼接一个字符串,再生成,再判断,直到没有关键字

通过唯一ID生成短链接

我们可以维护一个 ID 自增生成器。它可以生成 1、2、3…这样自增的整数 ID。当短网址服务接收到一个原始网址转化成短网址的请求之后,它先从 ID 生成器中取一个号码,然后将其转化成 62 进制表示法,拼接到短网址服务的域名http://xx.cn 后面,就形成了最终的短网址。最后,我们还是会把生成的短网址和对应的原始网址存储到数据库中

处理的流程跟上面一致

ps:xx.cn 这个域名,我笔者自己YY的,你改成你们自己的短域名即可。

写作不易,刚好你看到,刚好对你有帮助,动动小手,点点赞,有疑问的欢迎留言或者私信讨论

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【高阶数据结构】AVL树详解
因此,两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1962年发明了一种解决上述问题的方法:
YIN_尹
2024/01/23
1.8K0
【高阶数据结构】AVL树详解
12(13)个球1个不同重量称3次称出的详细分析
  因为网上这道题没有详细思路,我想我还是补个详细思路。这道题目描述是这样的:   有12个一模一样的球,其中11个重量一模一样,剩下的1个重量和其他的不一样。使用一个无砝码的天平称3次,找出重量不一样的这一个球,以及知道这个球比其他的球重还是轻。   这个题目似乎很早就出来了,估计有十几年吧,曾以不一样的身份出现在各个帖子里,有的时候号称是微软笔试题,也曾被称为google笔试题,还有说是腾讯笔试题的。至于它真实的出处,我们不必在意。另外还有13个球的版本的,只是只要找出球就行了。倒是这道题的详细解题步骤
窗户
2018/02/07
1.8K0
赛事解析|乒乓球时序动作定位大赛亚军方案分享
时序动作定位(提案生成)是计算机视觉和视频分析领域一个具有挑战性的任务。本次比赛不同于以往的ActivityNet-TAL,FineAction等视频时序检测动作定位比赛,采用了更精细的动作数据集–乒乓球转播画面,该数据集具有动作时间跨度短、分布密集等特点,给传统模型精确定位细粒度动作带来了很大挑战。
用户1386409
2022/09/01
7030
赛事解析|乒乓球时序动作定位大赛亚军方案分享
2023复试——机试随笔【c++】【考研】
建议用嘴说说,,写代码时间一长脑子一涨,很容易码错,找了半天错误,和正确结果就差一天,不就是2月的问题吗,不就是闰年判断有问题吗???
来杯Sherry
2023/07/24
4190
《机器学习》学习笔记(三)——线性模型
分类的核心就是求出一条直线w的参数,使得直线上方和直线下方分别属于两类不同的样本
荣仔_最靓的仔
2021/02/02
1.6K0
《机器学习》学习笔记(三)——线性模型
千亿关系链下的新增共同好友计算
本文介绍了基于内外存数据结构的三维空间数据的高效关联规则挖掘算法。该算法使用一种改进的时空关联规则挖掘算法,同时利用了三维空间数据的特点和内外存数据结构的优势,提高了算法的效率。具体来说,该算法首先利用外存数据结构将三维空间数据转换为二维数据,然后利用内存数据结构进行关联规则挖掘。实验结果表明,该算法在处理大规模三维空间数据时具有较好的效率和准确性。
杨光
2017/09/22
3.4K0
千亿关系链下的新增共同好友计算
二叉树的应用详解 - 数据结构
1、排序树——特点:所有结点“左小右大 2、平衡树——特点:所有结点左右子树深度差≤1 3、红黑树——特点:除了具备二叉查找树的特性外还有5个特性以致保持自平衡。 4、字典树——由字符串构成的二叉排序树 5、判定树——特点:分支查找树(例如12个球如何只称3次便分出轻重) 6、带权树——特点:路径带权值(例如长度) 7、最优树——是带权路径长度最短的树,又称 Huffman树,用途之一是通信中的压缩编码。
黄规速
2022/04/14
1.4K0
二叉树的应用详解 - 数据结构
强化学习从基础到进阶-案例与实践[4]:深度Q网络-DQN、double DQN、经验回放、rainbow、分布式DQN
,但是这样的方法存在很大的局限性。例如,现实中的强化学习任务所面临的状态空间往往是连续的,存在无穷多个状态,在这种情况下,就不能再使用表格对价值函数进行存储。价值函数近似利用函数直接拟合状态价值函数或动作价值函数,降低了对存储空间的要求,有效地解决了这个问题。
汀丶人工智能
2023/10/11
9000
强化学习从基础到进阶-案例与实践[4]:深度Q网络-DQN、double DQN、经验回放、rainbow、分布式DQN
经典优化算法之分治法(Divide-and-Conque Algorithm)
分治分治,即分而治之。分治,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)……直接说就是将一个难以直接解决的大问题,分割成一些规模比较小的相同的小问题,以便各个击破,分而治之。
用户1621951
2019/10/18
5.9K0
经典优化算法之分治法(Divide-and-Conque Algorithm)
零基础学并查集算法
并查集是我暑假从高手那里学到的一招,觉得真是太精妙的设计了。以前我无法解决的一类问题竟然可以用如此简单高效的方法搞定。不分享出来真是对不起party了。(party:我靠,关我嘛事啊?我跟你很熟么?) 来看一个实例,杭电1232畅通工程 首先在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你哪些对城镇之间是有道路直接相连的。最后要解决的是整幅图的连通性问题。比如随意给你两个点,让你判断它们是否连通,或者问你整幅图一共有几个连通分支,也就是被分成了几个互相独立的块。像畅通工程这题,问还需要修几条路,
Angel_Kitty
2018/04/08
1.2K0
零基础学并查集算法
【高阶数据结构】B-树详解
以上结构适合用于数据量相对不是很大,能够一次性存放在内存中,进行数据查找的场景(内查找)。
YIN_尹
2024/02/08
8260
【高阶数据结构】B-树详解
【Python机器学习】系列五决策树非线性回归与分类(深度详细附源码)
查看之前文章请点击右上角,关注并且查看历史消息 所有文章全部分类和整理,让您更方便查找阅读。请在页面菜单里查找。 相关内容:(点击标题可查看原文) 第1章 机器学习基础 将机器学习定义成一种通过学习经验改善工作效果的程序研究与设计过程。其他章节都以这个定义为基础,后面每一章里介绍的机器学习模型都是按照这个思路解决任务,评估效果。 第2章 线性回归 介绍线性回归模型,一种解释变量和模型参数与连续的响应变量相关的模型。本章介绍成本函数的定义,通过最小二乘法求解模型参数获得最优模型。 第3章 特征提取与
量化投资与机器学习微信公众号
2018/01/29
2K0
智能营销增益(Uplift Modeling)模型——模型介绍(一)
Uplift Modeling在智能营销中非常重要,一般来说个性化营销人群中存在四类:
悟乙己
2021/12/07
12K0
智能营销增益(Uplift Modeling)模型——模型介绍(一)
论概率:从局部随机性到整体确定性
以两个随机事件为例,一个随机事件发生或者另一个随机事件发生的概率,也就是这两个随机事件发生其一的概率,等于两个随机事件各自发生概率的和。
全栈程序员站长
2022/09/02
1.5K0
论概率:从局部随机性到整体确定性
深度学习500问——Chapter02:机器学习基础(3)
2. 投影思想:找出最能够代表原始数据的投影方法。被PCA降掉的那些维度只能是那些噪声或是冗余的数据。
JOYCE_Leo16
2024/03/19
1550
深度学习500问——Chapter02:机器学习基础(3)
计算机组成原理:从电、电磁、继电器到数字计算机(13k字)
科学Sciences导读:公号对话框发送“计算机组成原理”获取10k字4表65图25页PDF计算机组成原理:从电、电磁、继电器到数字计算机。关键词:电(electricity),电磁(electromagnetic),数字计算机(digital computer),计算机(computer),组成原理(composition principle)。QinlongGEcai微信被封,转向自用、科普文章、学术论文OAJ电子刊免费开放获取。
秦陇纪
2020/11/05
1.8K0
计算机组成原理:从电、电磁、继电器到数字计算机(13k字)
《王道》数据结构笔记整理2022级_数据结构笔记整理
1.数据:数据是信息的载体,是描述客观事物属性的数、字符以及所有能输入到计算机中并被程序识别和处理的符号的集合。
全栈程序员站长
2022/09/22
3.1K0
《王道》数据结构笔记整理2022级_数据结构笔记整理
刚体力学整理
质点:一个有质量的几何点,忽略其大小、形状及内部结构的影响,在空间只占据一个点的位置。它是对实际研究对象的简化,理想模型。
算法之名
2023/10/16
1.1K0
刚体力学整理
空间组学 | 用 moscot 对细胞进行时空动态分析
◉ 这是通用单细胞基因组分析的最优传输(OT)管道示意图(从左到右):实验变化(例如时间点和不同的空间切片)导致不同的细胞群体。◉ 以前的生物学知识(例如增殖率和空间排列)通常是可用的,并且应该用来指导映射过程。◉ 最优传输通过最小化位移成本来对齐细胞分布。◉ 学习到的映射促进了各种下游分析机会。◉ Moscot 引入了三个关键创新,从而释放了最优传输的全部潜力。◉ 首先,它支持所有模型中的多模态数据。◉ 其次,它克服了以前的可扩展性限制,使得能够进行图集规模的应用。◉ 第三,Moscot 是一个统一的框架,在生物学问题中具有一致的API,这将促进易用性,并能够以简单的方式扩展到新问题。◉ 面板a和b是使用BioRender创建的(https://www.biorender.com)。
生信菜鸟团
2025/03/06
1350
空间组学 | 用 moscot 对细胞进行时空动态分析
Science:工具使用和语言句法在基底神经节共享计算机制和神经表征
在语言和其他认知计算研究过程中的一个重要问题是:工具使用是否与语言的句法加工共享计算过程?因为,使用工具的行为可以被认为是给运动计划增加了一个层级结构。而在语言领域,句法加工相互依赖的语言基本元素(即词),它也是一个具有层级结构的认知功能。那么语言的句法层级结构是否具有特异的神经加工机制呢?
用户1279583
2022/02/28
6550
Science:工具使用和语言句法在基底神经节共享计算机制和神经表征
推荐阅读
相关推荐
【高阶数据结构】AVL树详解
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档