-
Notifications
You must be signed in to change notification settings - Fork 3
/
hashids.go
144 lines (125 loc) · 3.56 KB
/
hashids.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// https://github.com/speps/go-hashids 的方法封装,数字类型的ID转换为随机字符串ID
// 用法示例
// package main
// import (
// "log"
// "github.com/axiaoxin-com/goutils"
// )
// func main() {
// salt := "my-salt:appid:region:uin"
// minLen := 8
// prefix := ""
// h, err := goutils.NewHashids(salt, minLen, prefix)
// if err != nil {
// log.Fatal(err)
// }
// var id int64 = 1
// strID, err := h.Encode(id)
// if err != nil {
// log.Fatal(err)
// }
// log.Printf("int64 id %d encode to %s", id, strID)
// int64ID, err := h.Decode(strID)
// if err != nil {
// log.Fatal(err)
// }
// log.Printf("string id %s decode to %d", strID, int64ID)
// }
// 运行结果:
// go run example.go
// 2020/02/26 13:28:11 int64 id 1 encode to 8Gnejq6A
// 2020/02/26 13:28:11 string id 8Gnejq6A decode to 1
package goutils
import (
"log"
"strings"
"github.com/speps/go-hashids"
)
// Hashids 封装hashids方法
type Hashids struct {
HashID *hashids.HashID
HashIDData *hashids.HashIDData
prefix string
}
// NewHashids 创建Hashids对象
// salt可以使用用户创建记录时的用户唯一身份标识+当前时间戳的字符串作为值
// minLength指定转换后的最小长度,随着数字ID的增大长度可能会变长
func NewHashids(salt string, minLength int, prefix string) (*Hashids, error) {
hd := hashids.NewData()
hd.Salt = salt
hd.MinLength = minLength
h, err := hashids.NewWithData(hd)
if err != nil {
return nil, err
}
return &Hashids{
HashID: h,
HashIDData: hd,
prefix: prefix,
}, nil
}
// Encode 将数字类型的ID转换为指定长度的随机字符串ID
// int64ID为需要转换的数字id,在没有自增主键ID时,可以采用当前用户已存在的记录数+1作为数字id,保证该数字在该用户下唯一
func (h *Hashids) Encode(int64ID int64) (string, error) {
idstr, err := h.HashID.EncodeInt64([]int64{int64ID})
if err != nil {
return "", err
}
return h.prefix + idstr, nil
}
// Decode 将生成的随机字符串ID转为为原始的数字类型ID
func (h *Hashids) Decode(hashID string) (int64, error) {
if h.prefix != "" {
hashID = strings.TrimPrefix(hashID, h.prefix)
}
idSlice, err := h.HashID.DecodeInt64WithError(hashID)
if err != nil {
return 0, err
}
return idSlice[0], nil
}
// MustNewHashids 创建Hashids对象
// salt可以使用用户创建记录时的用户唯一身份标识+当前时间戳的字符串作为值
// minLength指定转换后的最小长度,随着数字ID的增大长度可能会变长
func MustNewHashids(salt string, minLength int, prefix string) *Hashids {
hd := hashids.NewData()
hd.Salt = salt
hd.MinLength = minLength
h, err := hashids.NewWithData(hd)
if err != nil {
panic(err)
}
return &Hashids{
HashID: h,
HashIDData: hd,
prefix: prefix,
}
}
// IntHashEncode 返回int的hash值
func IntHashEncode(i int, salt string, minLength int, prefix string) string {
h, err := NewHashids(salt, minLength, prefix)
if err != nil {
log.Println(err)
return ""
}
s, err := h.Encode(int64(i))
if err != nil {
log.Println(err)
return ""
}
return s
}
// IntHashDecode 返回hash值对应的int
func IntHashDecode(s string, salt string, minLength int, prefix string) int {
h, err := NewHashids(salt, minLength, prefix)
if err != nil {
log.Println(err)
return 0
}
i, err := h.Decode(s)
if err != nil {
log.Println(err)
return 0
}
return int(i)
}