拿論壇來講,通常帖子在數據庫裏的id都是順序遞增的,可是你可能不想在url上直接把id暴露出來,以避免爬蟲直接遍歷id爬取你的內容,給你帶來損失。那如今你就可使用Hashids把這個id搞亂,讓它失去順序性,沒法直接遍歷,這樣就能夠直接提升了爬蟲的門檻。著名的Youtube網站就是這麼作的。算法
咱們來看看它怎麼使用 首先安裝一下 pip install hashids
mongodb
咱們看到hashids不只能夠編碼一個整數,還能夠一次編碼多個整數。解碼的時候不須要對字符串進行分割,能夠直接解碼成多個整數。這在存儲一個帖子的相關帖子時給咱們多了一種選擇,通常咱們使用json打包多個帖子id放在帖子表的一個字段裏,如今咱們就可使用hashids把它們編碼成一個字符串塞進去了,能夠節省必定的存儲空間。不過,除此以外我想不到編碼多個整數有什麼其它的用途了。數據庫
hashids須要提供一個salt值,至關於編解碼的私鑰,別人不知道你的私鑰,就沒法編碼出對應的帖子的展示key,也沒法經過url上的展示key解碼出對應的帖子id。因此想直接遍歷你的帖子服務那就作不到了。json
如今咱們試試隨便提供字符串,對它進行解碼會怎樣安全
咱們看到這些字符串都是非法,因此hashids沒法解碼出對應的整數。網站
下面咱們對一段連續整數進行編碼搜索引擎
能夠發現編碼以後的值在直覺上是沒有任何規律可言的。編碼
鑑於hashids是如此的小巧,筆者隨後對它的源代碼進行了一番研究。首先看看它的構造器url
咱們發現能夠設置編碼後字符串的最小長度。若是你不設置這個最小長度,對於一個從0開始的自增id,編碼出來的字符串長度一開始只有2位,可是隨着id的增加,編碼後的長度也愈來愈大,可是最終這個長度值愈來愈穩定,由於位數越大能夠表達的數值就越多。若是咱們設置了這個最小長度,在id沒有恐怖的快速增加的狀況下,那麼編碼出的長度一開始就是很是穩定的。3d
而後咱們還能夠設置映射字典。默認是base64[26+26+10]編碼,若是你不喜歡大小寫敏感,能夠改爲base36[26+10]編碼,甚至能夠改爲火星文,若是你真這麼無聊的話。
注意火星文的字典必須是unicode類型。否則你編碼獲得的不是火星文,而是亂碼。具體實現算法我就跳過了,有點複雜,我就不講了。
而後它還支持對16進制字符串進行編解碼,看來mongodb的id也能夠歸入進來了。
最後算法的實現原理,仔細研究了一下,有點複雜,很難三言兩語講清楚,有興趣的話讀者仍是本身閱讀官方文章吧。算法的做者不保證安全性,不建議將hashids用在安全領域。
維基百科提到一個理想的hash算法須要知足下面3個特性
hashids知足第1和第3條,正向計算hash很快,hash值徹底沒有碰撞,保證了惟一性。若是知道salt值,還能夠逆向經過hash值計算出原值。那第2條是否知足取決於你的salt祕鑰有多容易被攻擊者拿到。若是你的salt祕鑰來自於經常使用字典單詞,那攻擊者能夠經過彩虹字典快速將祕鑰破解。你把祕鑰好好保護,設置的隨機一點長度長一些,安全性仍是能夠獲得保障的。
最後你可千萬別把祕鑰搞丟了,一旦搞丟了,就意味着全部帖子的展示id須要從新計算一邊,變的跟之前不同了,搜索引擎收錄的全部網頁就失效了,別人外鏈過來的地址全都打不開,這無疑會給你的網站帶來很大的損失。
閱讀相關文章,關注公衆號「碼洞」