目录
3.分布式发号器snowflake(新短url与源url无关,与发号器有关)
1.短网址的长度?---长度<=7的62进制数(大小写字母加数字),最多可生成568亿个短链
3.长网址与短网址的关系是一对一还是一对多映射?---一对多
5.如何预防攻击?---redis缓存长网址->ID,而不是ID->长网址
一、算法设计方案
1、固定长度分段(4组6位字符,任选一组)
32位md5串=4段*8位,其中的8位看成16进制a,(bin2hex(a) & 0x3fffffff)=30位=6段*5位,其中的5位看作16进制b,(b & 0x0000003D)=0~61
① 将长网址用md5算法生成32位签名串,分为4段,,每段8个字符;
② 对这4段循环处理,取每段的8个字符, 将他看成16进制字符串与0x3fffffff(30位1)的位与操作,超过30位的忽略处理;
③ 将每段得到的这30位又分成6段,每5位的数字与0x0000003D(61)的位与操作,结果作为字母表的索引取得特定字符,依次进行获得6位字符串;
④ 这样一个md5字符串可以获得4个6位串,取里面的任意一个就可作为这个长url的短url地址。
2. 可选长度分段(短链长度需能被30整除)
上文把短网址长度固定=6位,进一步可改进成动态调整的,如5、6、10、15位等,使其是30个质数之一,能被30整除就行。
1、固定长度分段(4组6位字符,任选一组) function shortUrl($url_arr, $url_pre = 'https://t.cn/') {
|
2. 可选长度分段(短链长度需能被30整除) function shortUrl($url_arr, $url_len, $url_pre = 'https://t.cn/') {
|
3.分布式发号器snowflake(新短url与源url无关,与发号器有关)
snowflake生产的ID是一个18位的long型数字,二进制结构表示如下(每部分用-分开):
0 - 00000000 00000000 00000000 00000000 00000000 0 - 00000 - 00000 - 00000000 0000
1 + 41 + 10(10位workId或者5位datacenterId+5位workerId)+ 12 = 64位(恰好是一个Long型,转换为字符串长度为18)
第1位未使用,
接下来41位为毫秒级时间(41位的长度可以使用69年,从1970-01-0108:00:00开始),
然后是5位datacenterId(最大支持25=32个,二进制表示从00000-11111,也即是十进制0-31),和5位workerId(最大支持25=32个,原理同datacenterId),所以datacenterId*workerId最多支持部署1024个节点,
最后12位是毫秒内的计数(12位的计数顺序号支持每个节点每毫秒产生2^12=4096个ID序号).
单台机器实例,通过时间戳保证前41位是唯一的,分布式系统多台机器实例下,通过对每个机器实例分配不同的datacenterId和workerId避免中间的10位碰撞。最后12位每毫秒从0递增生产ID,再提一次:每毫秒最多生成4096个ID,每秒可达4096000个(每秒400万+个ID)。理论上,只要CPU计算能力足够,单机每秒实测10w+
//亲测可用 class SnowFlake { public function initProperty($totalProcess = 1, $pid = 1){//初始化成员属性 protected static function getCurMiltime(){//取当前时间毫秒 public function createShortUrl($url_pre = 'https://t.cn/', $url_len = 6) {//从发号器的id生成短链 |
调用: $snowflake = new SnowFlake(0, 1); |
4.分布式发号器的优化
多进程下 执行防止重复 将进程id 传入赋值给 workid 就可以保证单机下多进程不重复
详见:https://www.jianshu.com/p/5b3570373c62
二、重点解答
1.短网址的长度?---长度<=7的62进制数(大小写字母加数字),最多可生成568亿个短链
答:长度不超过7的字符串,由大小写字母加数字共62个字母组成。a-zA-Z0-9这62位取6位组合,可产生62^6=568亿个组合数量
2.如何计算短网址?---分布式发号器
答:分布式发号器。
3.长网址与短网址的关系是一对一还是一对多映射?---一对多
答:一对多。
4.301还是302重定向?---302重定向
答:
5.如何预防攻击?---redis缓存长网址->ID,而不是ID->长网址
答:
6.十进制整数与N进制(N<=62)的互转
答: