大家好,我是渔夫子。本号新推出「go工具箱」系列,意在给大家分享使用go语言编写的、实用的、好玩的工具。
今天给大家推荐的工具是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的。个人认为是因为通过取余的方式进行进制转换的原理,那么负数和正数可能会产生同样的余数而导致非唯一性。
该包特点:
对非负整数都可以生成唯一短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 = 8h, _ := 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
---特别推荐---
特别推荐:一个专注go项目实战、项目中踩坑经验及避坑指南、各种好玩的go工具的公众号,「Go学堂」,专注实用性,非常值得大家关注。点击下方公众号卡片,直接关注。关注送《100个go常见的错误》pdf文档。