今天给大家推荐的工具是hashids。该工具可以将一个正整数转换成长度较短、唯一且不连续的ID值。一般适用于生成用户ID,但又不想用有规律的ID的场景。
原理分析:将长字符串转换成短字符串的本质是进制转换。将小进制数往大进制数上转换就会变短,将大进制数往小进制数上转换就会变长。比如将一个二进制数转换成十进制就可以将二进制数变短。如下将1010转换成十进制就是 10,转换成十六进制就是a。该hashids包的原理也是一样,是基于62进制进行转换的。如下:
func hash(input int64) []rune{
//a-z及A-Z及0-9共62个数
var alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
for {
//通过取余法进行进制转换
r := alphabet[input%int64(len(alphabet))]
result = append(result, r)
input /= int64(len(alphabet))
if input == 0 {
break
}
}
return result
}
无序性是通过Fisher–Yates shuffle的算法将alphabet进行重排得到。该算法可以参考文末的参考链接,非常简单。
该包是对非负整数产生唯一ID的。个人认为是因为通过取余的方式进行进制转换的原理,那么负数和正数可能会产生同样的余数而导致非唯一性。
该包特点:
基本使用
hd := hashids.NewData()
hd.Salt = "my salt"
h, _ := hashids.NewWithData(hd)
id, _ := h.Encode([]int{1}) //只要这里的ID或salt值不一样,最终的id就不一样
fmt.Println(id) // 最终输出 OL
设置生成最短ID的位数,如下设置最小长度是8位:
hd := hashids.NewData()
hd.Salt = "my salt"
hd.MinLength = 8
h, _ := hashids.NewWithData(hd)
id, _ := h.Encode([]int{1}) //只要这里的ID或salt值不一样,最终的id就不一样
fmt.Println(id) // 最终输出 On5OLgYy
更多项目详情请查看如下链接:
开源项目地址:https://github.com/speps/go-hashids
开源项目作者:speps
参考链接:
Fisher–Yates shuffle算法:https://zhuanlan.zhihu.com/p/259652066
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8