背景:我们手机总会收到商品推销的短信,短信中包含一个商品链接,既然是个网页链接,它一定是http或者https的,但是短信中的链接特点是很短,从链接中看不出任何的信息,而且没有超文本传输协议,不同于常用的URL格式。这就是短链系统。

短链系统
这个链接就是一个短链URL,使用它
短链系统的优点
- 屏蔽URL中的信息,相对更加安全
- 让短息更简洁
- 利于营销
短链系统的核心原理
短链系统的组成:域名+随机码(其中域名在书面表达上可以不具备任何意义),那我收到的这条短信,3.cn/v就是个域名,ey8j是随机码。
在数据库表中存储短链和实际可以用于访问的URL的映射关系,将短链发送给用户,用户点击短链后,根据映射关系找到访问的URL,然后进行重定位跳转。
重定位跳转
我们在访问网页的时候,当资源的位置发生改变的时候,会出现跳转,资源重定位常用的转移码是301,302
301(资源永久重定位):首次请求是访问短链系统,获取短链对应的长链URL,后面再访问时不经过短链系统,而是直接使用首次访问时获取的长链URL进行访问
302(资源临时重定位):每一次访问短链时都要经过短链系统获取对应的长链URL,通过长链URL进行访问
短链系统一般使用的是302资源临时重定位

数据库设计
1 2 3 4 5 6 7 8 9 10 11
| CREATE TABLE short_url_map ( id int unsigned NOT NULL AUTO_INCREMENT, long_url varchar(160) NOT NULL COMMENT '原始长链接', short_url varchar(10) NOT NULL COMMENT '短链接代码', gmt_create datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', gmt_modified datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (id), UNIQUE KEY uk_short_url (short_url), KEY idx_gmt_create (gmt_create) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='长短链接映射表'; DESC short_url_map
|

那怎么产生短链系统呢?
因为短链是由 域名+随机码组成的,所以如何生成一个随机码(这个随机码要是全局唯一的)是短链系统的关键
生成随机码通常有三种方法:Base62、Hash、全局唯一ID(雪花算法)
Base62
Base62 表示法是一种基数为62的数制系统,包含26个英文大写字母(A-Z),26个英文小写字母(a-z)和10个数字(0-9)。这样,共有62个字符可以用来表示数值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #include <string> #include <random> #include <algorithm> #include <iostream> using namespace std; class RandomCodeGenerator { private: static const string CHAR_62; static mt19937_64 random_engine; // C++ 中用于生成高质量伪随机数的静态随机数引擎 static uniform_int_distribution<int> dist;
public: static string generateRandomCode(int length) { string result; result.reserve(length); //预分配空间
for (int i = 0; i < length; ++i) { int rndCharAt = dist(random_engine) % CHAR_62.length(); char rndChar = CHAR_62[rndCharAt]; result.push_back(rndChar); }
return result; } };
// 初始化静态成员 const string RandomCodeGenerator::CHAR_62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; mt19937_64 RandomCodeGenerator::random_engine(random_device{}()); uniform_int_distribution<int> RandomCodeGenerator::dist(0, CHAR_62.length() - 1);
int main() { RandomCodeGenerator number; string result = number.generateRandomCode(5); cout << result << endl; system("pause"); }
|
Hash
①将长链进行哈希,截取前面的几个字符串作为随机数
②将长链进行哈希,然后再进行压缩(使用MurmurHash哈希算法将长链哈希成一个32位的10进制正数,然后再转换成62或者64进制(压缩),就可以得到一个6位的随机数)
使用雪花算法生成唯一ID