目錄
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)的互轉
答: