探究短信里的短链接是如何实现的

news2024/9/25 5:21:01

简介

我们日常在收短信的时候,会经常发现,他们的短信里的跳转链接,都是非常短非常短的,这是为什么呢?

因为现在短信新规出来,是按字数收费的,而不是按条。比如腾讯云短信新规,70字为一条,哪怕你是一条短信,100个字,就会按照两条来计费,这个时候短链接就有了相当大的优势。那么短链接是如何实现的呢?

短链接原理

其实就是在后台保存有短链和长链的映射关系,然后进行重定向,让浏览器跳转到对应的长链接。首先访问短链接,根据短链接查询数据库获取完整长链接,返回301或者302,让浏览器重定向到目标地址,浏览器跳转到长链接。

例子:当访问短链接,https://域名/xxx时,后端返回了302,同时多了一个Location响应头,值就是原始链接地址

解决方案

第一种是对 URL 进行hash运算,得到较短的hash值,Murmur哈希就是其中之一。既然是通过哈希函数,就避免不了哈希冲突。虽然这概率很低,但我们设计系统时需要考虑。

第二种对数据存储,由短链接跳转到长链接,肯定有必然的关系,我们需要把他们保存起来,存储的方式有Redis、Mysql等数据库。

例子:如果是Mysql存储,表结构大概有(自增id、短链接、长链接、创建时间)这些字段;我们可以通过生成的短链接,查询数据库是否有存在的短链接。不存在,直接存储;存在,需要二次拼接生成短链接,直到不存在为止,进行存储。如果当数据库数据变多,我们需要优化,短链接字段需要加唯一性索引。如果再一次优化,可以使用布隆过滤器,将新生成的短链接在布隆过滤器里进行查找,不存在直接插入数据库。

生成短链接方法

  1. 根据唯一自增id后,再转换为62进制字符串,生成短链接。优点:ID唯一,生成的短链不会重复和冲突;缺点:高并发下有性能瓶颈。
  2. 雪花算法。优点:高性能;缺点:生成的ID比较长。
  3. Redis自增。优点:高性能,高并发;缺点:是中间件,有维护成本。
  4. Hash算法,常见有MD5、SHA算法。但这里我们一般采用Google的Murmurhash算法,优点:哈希冲突的概率低,速度比MD5快,缺点:有几率哈希冲突

建表

CREATE TABLE `url_convert` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `longUrl` text,
  `shortUrl` varchar(256) DEFAULT NULL,
  `userId` int(11) DEFAULT '0',
  `count` int(11) DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

转短链接并加密

public static String getShortURL(String URL) {
        // 可以自定义生成 MD5 加密字符传前的混合 KEY
        String key = "QDGYJ";
        // 要使用生成 URL 的字符
        String[] chars = new String[]{"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", "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"

        };
        // 对传入网址进行 MD5 加密
        String hex = md5ByHex(key + URL);

        String[] resUrl = new String[4];
        for (int i = 0; i < 4; i++) {

            // 把加密字符按照 8 位一组 16 进制与 0x3FFFFFFF 进行位与运算
            String sTempSubString = hex.substring(i * 8, i * 8 + 8);

            // 这里需要使用 long 型来转换,因为 Inteper .parseInt() 只能处理 31 位 , 首位为符号位 , 如果不用long ,则会越界
            long lHexLong = 0x3FFFFFFF & Long.parseLong(sTempSubString, 16);
            String outChars = "";
            for (int j = 0; j < 6; j++) {
                // 把得到的值与 0x0000003D 进行位与运算,取得字符数组 chars 索引
                long index = 0x0000003D & lHexLong;
                // 把取得的字符相加
                outChars += chars[(int) index];
                // 每次循环按位右移 5 位
                lHexLong = lHexLong >> 5;
            }
            // 把字符串存入对应索引的输出数组
            resUrl[i] = outChars;
        }
        Random random = new Random();
        int j = random.nextInt(4);
        //随机取一个作为短链
        return resUrl[j];
    }

    /**
     * MD5加密(32位大写)
     *
     * @return List<Map < String, Object>>
     * @author DingYongJun
     * @date 2020/8/18
     */
    public static String md5ByHex(String src) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] b = src.getBytes();
            md.reset();
            md.update(b);
            byte[] hash = md.digest();
            String hs = "";
            String stmp = "";
            for (int i = 0; i < hash.length; i++) {
                stmp = Integer.toHexString(hash[i] & 0xFF);
                if (stmp.length() == 1)
                    hs = hs + "0" + stmp;
                else {
                    hs = hs + stmp;
                }
            }
            return hs.toUpperCase();
        } catch (Exception e) {
            return "";
        }
    }

重定向

@GetMapping("/getShortUrl")
@CrossOrigin
public ResultData<String> getShortUrl(String longUrl) {
    String shortUrl = URLUtils.getShortURL(longUrl);
    convertService.add(shortUrl, longUrl);

    return ResultData.success(RequestCode.SUCCESS.getCode(), "可以使用", shortUrl);

}

@GetMapping("/{shortUrl}")
@CrossOrigin
public RedirectView redirectView(@PathVariable String shortUrl) {
    saveArticleService.addCount(shortUrl);
    WxArticle longUrl = saveArticleService.getLongUrl(shortUrl);

    return new RedirectView(longUrl.getMediumUrl());
}

getShortUrl 接口,是把长连接转为短链接,获取短链接的数据,然后拿到短链接数据后,调用重定向接口,重定向到长连接。

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2067715.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

原生js中的防抖节流笔记

防抖,单位时间内&#xff0c;频繁触发&#xff0c;只执行最后一次 效果演示 优化前&#xff0c;不断触发&#xff0c;浪费性能 优化后&#xff0c;只在指定时间内触发 演示代码 import debounce from "/node_modules/lodash-es/debounce.js"; const oBox docu…

专业养生调理保健传承者——五指生望京店开业送健康

2024年8月22日&#xff0c;即处暑时节&#xff0c;五指生望京店盛情开业&#xff01;在这个暑意渐消的美好时节&#xff0c;望京店希冀为更多尊贵生命带来健康。 五指生成立于2001年&#xff0c;作为“全国五星级保健服务机构”&#xff0c;曾先后获得“首都文明单位”“北京市…

Java学习Day34:图书管理小项目

搭建过程 1.根据需求设计数据库 概念设计&#xff1a;使用ER图等工具设计数据库概念模型&#xff0c;明确实体、属性、关系。逻辑设计&#xff1a;将概念模型转换为数据库表结构&#xff0c;确定主键、外键、索引等。物理设计&#xff1a;根据数据库管理系统的特性进行物理存…

【运维】docker搭建portainer

1.拉取镜像 并 启动容器 1.1 拉取镜像 docker pull 6053537/portainer-ce1.2 启动容器 docker run -d --restartalways --name"portainer" -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock 6053537/portainer-ce2.访问地址 ip地址9000端口 密码&…

True XML cookbook

打开题目 看到登录口 随便输入admin&#xff0c;123456&#xff0c;然后抓包试一下 先按原来那道题的payload进行测试&#xff0c;payload和结果如下&#xff1a; <?xml version"1.0" ?> <!DOCTYPE llw [ <!ENTITY file SYSTEM "file:///flag&…

Linux驱动入门实验班——DAC模块驱动(附百问网视频链接)

目录 前言 一、 SPI数据结构 1.SPI设备驱动 2.SPI设备数据结构 二 、函数接口 1.spi_sync_transfer 2.spi_register_driver 三、DAC 1.数据格式 2.数据结构 四、源码 驱动 应用 课程链接 前言 在这里主要记录学习韦东山老师Linux驱动人入门实验班的笔记&#xff0…

计算机网络——HTTP与HTTPS协议

HTTP与HTTPS是应用层的协议。 目录 一、HTTP 二、HTTPS 三、HTTP与HTTPs对比 四、HTTP/1.0 HTT/1.1 HTTP/2有什么区别 五、HTTP常用请求方法&#xff1f;get/post区别&#xff1f; 六、HTTP的工作过程 七、HTTPS的工作过程 八、Cookie、Session、Token 一、HTTP 超…

【CAN总线测试】——CAN物理层测试

从0开始学习CANoe使用 从0开始学习车载测试 相信时间的力量 星光不负赶路者&#xff0c;时光不负有心人。 目录 1.最小通讯电压测试 2.最大通讯电压测试 3.显性位/隐性位输出电压测试 4.信号跳变沿测试 5.地偏移 6.终端电阻 1.7. CANH/CANL短路 1.8. CANH /GND短路 …

Verilog刷题笔记58

题目&#xff1a; Exams/2014 q3c 解题&#xff1a; module top_module (input clk,input [2:0] y,input x,output Y0,output z );parameter s03d000,s13d001,s23d010,s33d011,s43d100;always(*)begincase(y)s0:Y0x;s1:Y0~x;s2:Y0x;s3:Y0~x;s4:Y0~x;endcaseendassign z(y3b01…

Kafka运行机制(二):消息确认,消息日志的存储和回收,生产者消息分区

前置知识 Kafka基本概念https://blog.csdn.net/dxh9231028/article/details/141270920?spm1001.2014.3001.5501Kafka运行机制&#xff08;一&#xff09;&#xff1a;Kafka集群启动&#xff0c;controller选举&#xff0c;生产消费流程https://blog.csdn.net/dxh9231028/arti…

Verilog刷题笔记57

题目: Exams/2014 q3bfsm Given the state-assigned table shown below, implement the finite-state machine. Reset should reset the FSM to state 000. 解题&#xff1a; module top_module (input clk,input reset, // Synchronous resetinput x,output z );parameter…

ESP32-IDF 在 Ubuntu 下的配置

目录 一、安装准备二、获取 ESP-IDF三、设置工具四、使用案例 参考资料&#xff1a;官方文档&#xff1a;Linux 和 macOS 平台工具链的标准设置。 一、安装准备 参照官方文档&#xff0c;首先下载编译 ESP-IDF 所需要的软件包&#xff1a; sudo apt-get install git wget fl…

如何使用ssm实现基于Java的共享客栈管理系统

TOC ssm058基于Java的共享客栈管理系统jsp 第1章 绪论 1.1 课题背景 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。所以各…

一篇快速搞懂 JavaSE 高级特性(代码块,注解,枚举,异常处理,多线程,集合框架,泛型,反射,IO ......)

JavaSE 高级 一、面向对象&#xff08;高级&#xff09;1、单例模式&#xff08;Singleton&#xff09;2、代码块1&#xff09;静态代码块2&#xff09;非静态代码块 3、关键字 final4、抽象类与抽象方法&#xff08;abstract&#xff09;5、模板方法设计模式&#xff08;Templ…

利用GPT绘制流程图(无需下载任何软件

目录 什么是Flowchart Fun&#xff1f;如何利用GPT绘制流程图&#xff1f;步骤1&#xff1a;确定流程图的目的和内容步骤2&#xff1a;训练GPT编写流程图的文本描述步骤3&#xff1a;转换文本格式为可视化的流程图步骤4&#xff1a;调整和优化 结论小结&#xff1a; 什么是Flow…

SpringBoot【重修之HTTP协议】

request 请求&#xff0c;response 响应&#xff01; HTTP-协议的解析&#xff1a; 客户端&#xff1a;浏览器已经会自动解析了 服务端&#xff1a;通过Web服务器来解析&#xff01;【Tomcat , Jetty , WebLogic , WebSphere 】 Tomcat的研究学习 SpringBoot Web快速入门…

AIxBoard部署BLIP模型进行图文问答

一、AIxBoard简介 AIxBoard&#xff08;X板&#xff09;是一款IA架构的人工智能嵌入式开发板&#xff0c;体积小巧功能强大&#xff0c;可让您在图像分类、目标检测、分割和语音处理等应用中并行运行多个神经网络。它是一款面向专业创客、开发者的功能强大的小型计算机&#xf…

[Linux CMD] 查看系统资源 (持续更新中)

概述 在Linux中&#xff0c;有许多命令和工具可用于查看系统的资源使用情况。以下是一些常用的方式&#xff1a; top&#xff1a;top命令是最常见的实时系统监视工具之一。它显示了当前运行的进程列表&#xff0c;以及每个进程的CPU、内存使用情况、nice值等信息。top命令还会…

【Linux】简易日志工具项目

有些鸟儿是不应该被关在笼子里的&#xff0c; 因为他们的羽毛太丰润了。 当他们飞走&#xff0c;你会由衷地庆贺他获得自由。 --- 肖申克的救赎》--- 从零开始构建简易日志系统 1 日志1.1 什么是日志1.2 日志的意义1.3 为什么要构建自己的日志工具 2 构建自己的日志工具2.1…

带有限制编辑的PDF文件怎么取消编辑限制

在日常工作和学习中&#xff0c;我们经常会遇到一些带有“限制编辑”的PDF文件。这些文件由于设置了密码保护&#xff0c;使得我们无法直接编辑、复制或打印其中的内容&#xff0c;给信息的处理和利用带来了诸多不便。然而&#xff0c;通过一些有效的方法和工具&#xff0c;我们…