問題
為什麼要對 int 類型的資料加密,它的應用場景是什麼?
比如:有一個商品詳情界面 URL 為 /product/1001,這種情況很容易被别人猜測,比如輸入 /product/1002、/product/1003 嘗試着去檢視詳情,這樣的話資訊就暴露了,如果别人想抓資料的話,隻需要将後面的 ID 遞增抓取就可以了,怎麼解決這個問題?
比如:有一個使用者邀請碼需求,使用者可以将自己的邀請碼分享出去,當新使用者使用這個邀請碼注冊的時候,就會給邀請者和被邀請者雙方發獎勵,通過 URL /user/1001 注冊的,表示使用者ID為 1001 的邀請的,這樣使用者ID很容易被修改,怎麼解決這個問題?
分析
上面的兩個場景都是需要對 int 類型的資料進行加密,避免 ID 洩露。
需要滿足以下特性:
- 支援自定義 salt,保證加密後的是獨一無二。
- 支援加密和解密。
- 支援多語言。
解決方案
推薦一個開源的類庫。
官網位址:https://hashids.org/
支援多語言,包很小,使用也非常簡單。
下面給大家分享在 Go 中使用的。
Go 代碼分享
先說結果:我将 1001 加密成 1oEpdkEzWA,1002 加密成 NnlzvxEORb。
具體實作看如下代碼。
// 加密
func Encrypt(salt string, minLength int, params []int) string {
hd := hashids.NewData()
hd.Salt = salt
hd.MinLength = minLength
h, err := hashids.NewWithData(hd)
if err == nil {
e, err := h.Encode(params)
if err == nil {
return e
}
}
return ""
}
// 解密
func Decrypt(salt string, minLength int, hash string) []int {
hd := hashids.NewData()
hd.Salt = salt
hd.MinLength = minLength
h, err := hashids.NewWithData(hd)
if err == nil {
e, err := h.DecodeWithError(hash)
if err == nil {
return e
}
}
return []int{}
}