歡迎進入我的博客:blog.scarlettbai.com查看更多文章
最近接到一個需求,要批量生成推廣碼,首先我們知道推廣碼的特效有如下兩點:
1:不可重復
2:不可以被推測出
關於這兩點,我們的思路大體分為如下幾類:
1:每次生成一個隨機碼後查數據庫是否有相同的,有則重新生成(每次都要訪問數據庫,導致效率極低,不推薦)
2:依據數據庫的主鍵作為唯一鍵,進行打亂或插入操作,如主鍵為8000001,取出後生成3位(據需求增減)隨機數或字母,插入主鍵值中,構成如8000E0V0S1D這種串,可保證推廣碼不重復及不可推測出(這種方式也需要連接數據庫取主鍵,當然可以一次性預生成所需數目的主鍵,然後生成對應推廣碼後更新進數據庫,效率會高一些)
3:利用算法來保證值唯一,如UUID等,本篇重點介紹此種方式(不需連接數據庫,算法選擇合適則效率很高)
具體實現
上面說了,本文重點討論利用算法實現不重復性,首先我們會想到最簡單的方式:UUID,我們來看下具體效果:
圖中可以看出,UUID生成的隨機串去掉-後長度為32位,雖然可以保證幾乎絕對不會出現重復情況且支持多線程並發也不會重復,但是長度太長,不太實用。
既然UUID被淘汰了,那麼接下來我們來看下我們最常接觸的SHA算法:
從圖中可以看出,SHA算法生成的串也明顯太長,淘汰。
接下來我想到了對稱加密算法中的RC4,他可以保證密文長度和原字符串長度一樣,關於RC4算法本篇不多描述,大家有興趣可以上google百度一下,算法網上也有一大堆,大家可以隨便下一個就好,此處密文選為自增的數字,秘鑰寫死,接下來我們看一下效果:
圖中可以看出,生成的碼不在字母及數字范圍內,不可能拿這些碼給用戶作為推廣碼,那麼最簡單的一個方式是,將這個碼轉換為16進制,效果如下:
大家可以看到,此時密文都成了我們所熟知的字母和數字,但是長度變為了原字符長度的2倍,不過依舊算可以接受,但是看加密後的密文全都是連續性的,不滿足推廣碼第二點的可推測,而且由於私鑰全都一樣容易被破解,此處我們不需求解密,所以可以直接把私鑰換成UUID,來看下效果:
可以看到,此處生成的密文不再可以推測出,滿足了我們的需求,那麼對於是否會重復,我們再來做個測試,此處選用的需加密字符串長度為7位:
加密結果用別的方式轉換為我們常用的字母和數字,樓主本處是沒有特殊需求,所以直接采用了轉換16進制這種快捷偷懶的方式。