打開我的簡書首頁鬼吵,在地址欄上可以看到這樣的地址
作為一個web開發(fā)者應(yīng)該知道這里的users后面的那串"066ab87a062b"必定是我的ID,這個ID肯定是唯一的卵皂。這就是今天要討論的,怎樣生成唯一的ID?
如果你是一個初級的web開發(fā)者,那么你可能不會去生成這種唯一的ID,因為有一個很簡單的方法已經(jīng)幫我們搞定了這個事情戴质,那就是數(shù)據(jù)庫。
比如我們往數(shù)據(jù)庫的用戶表中插入一個用戶踢匣,數(shù)據(jù)庫的自增鍵就會生成一個唯一的ID告匠,當(dāng)然這種ID是很簡單的,就是從1開始自增离唬,這樣就不會重復(fù)后专。當(dāng)然這里有很大的安全隱患,從鏈接上多觀察一下输莺,就能發(fā)現(xiàn)規(guī)律戚哎。如果簡書現(xiàn)在的鏈接是這樣的:
再多看看其他用戶的簡書首頁地址,你發(fā)現(xiàn)也是一個數(shù)字嫂用,并且修改幾個連續(xù)的數(shù)字大多數(shù)能查看到其他用戶型凳,那么現(xiàn)在我就可以從ID為1開始遍歷,就可以知道簡書有多少注冊用戶了嘱函。是不是算暴露了信息甘畅?當(dāng)然黑客可以做的事情遠(yuǎn)遠(yuǎn)不止這些。
這個時候我們就得想一個比較復(fù)雜的生成唯一ID的想法。
一般來說疏唾,我們都會想到用當(dāng)前系統(tǒng)時間來做這件事情蓄氧,比如最簡單的是unix時間戳,像這樣
time();
//1429874998
一般情況下這樣是行不通的槐脏,因為unix時間戳只是精確到秒喉童,同一秒有兩個人注冊怎么辦?
我記得我一開始實習(xí)那會用這個方法來生成唯一ID
time() . rand(1, 10000);
//142987499812
時間戳后面加一個隨機數(shù)顿天,這樣把一秒鐘分成10000份泄朴,重復(fù)的概率只有萬分之一,對于一般的情況已經(jīng)能夠搞定了露氮。
但是精明一點的人肯能會猜到你是在用10位的時間戳加一個隨機數(shù)字,那怎么辦钟沛?
第一反映自然是加密:
md5(time() . rand(1, 10000));
//141464D2619764441D30A285ED4478F5
不可逆的加密算法有很多畔规,比如md5,sha1等,當(dāng)然如果使用可逆的加密算法容易被看出來恨统。這樣加密一般很難破解了叁扫,如果你還覺得不夠安全,可以在加密前后進(jìn)行一系列字符串操作畜埋,比如反轉(zhuǎn)莫绣。這樣就非常難以破解了。當(dāng)然也有問題悠鞍,那就是ID變得很長很長对室。而且似乎也沒有解決生成唯一ID的關(guān)鍵問題。
生成唯一ID的關(guān)鍵問題就是唯一咖祭,安全問題次之掩宜,不是說安全不重要,而是如果連生成唯一ID都解決不了么翰,安全就沒有什么可談的了牺汤,系統(tǒng)本身就是不穩(wěn)定不安全的。
上述的方法還是有一定的概率生成重復(fù)ID的浩嫌,雖然只有萬分之一檐迟,但如果剛好兩個人在同一秒注冊,剛好就生成了一樣的呢码耐?
php提供了一個生成唯一ID的函數(shù):
uniqid();
//553a2f5bad51f
這個生成的ID就和簡書的ID非常像了追迟。
但是這個函數(shù)也不一定會生成唯一的ID,原因是uniqid() 函數(shù)基于以微秒計的當(dāng)前時間伐坏,生成一個唯一的 ID怔匣;基于微妙的意思就是如果并發(fā)數(shù)非常非常高的時候,在同一個毫秒里面有兩個人注冊,那么也是會生成唯一的ID每瞒。
正真做到不重復(fù)要怎么辦金闽?
一種方法是結(jié)合時間和數(shù)據(jù)庫生成的ID,這兩者結(jié)合起來就是唯一的了剿骨。
至于怎么結(jié)合可以根據(jù)自己的需求或者喜好代芜。這樣生成的ID只要不進(jìn)行不可逆加密還可以按時間來排序。
還有一種方法是不借助數(shù)據(jù)庫那個唯一ID浓利,而是將注冊流程改為嚴(yán)格的單線程挤庇,也就是每次只處理一個,那這樣時間戳就是唯一的了贷掖,生成方法也就可以隨意發(fā)揮了嫡秕。當(dāng)然了,一兩秒的等待用戶還是可以接受的苹威。
怎么做到嚴(yán)格的單線程處理注冊流程昆咽?
第一種簡單的就是假設(shè)你已經(jīng)控制好了系統(tǒng)是單線程處理的,我記得以前聽過一個鴕鳥算法牙甫,像鴕鳥一樣將頭埋在沙子里面掷酗,什么也不做,假裝看不到窟哺,有時候這何嘗不是一種好的生活態(tài)度呢泻轰。ok,繼續(xù)說且轨,假設(shè)以微妙為單位浮声,這對于90%的系統(tǒng)已經(jīng)能滿足了,因為網(wǎng)站的量根本沒有那么大殖告。
第二種方法是用隊列來處理阿蝶,雖然牛刀殺雞,但也算是個方法黄绩。
講這么多大概講完了今天想到的東西羡洁,最近有點感觸就是,遇到的東西多思考你將可能發(fā)現(xiàn)更多的好玩的東西爽丹。