-
Notifications
You must be signed in to change notification settings - Fork 0
/
passwd.go
132 lines (119 loc) · 3.27 KB
/
passwd.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
package vege
import (
"crypto/hmac"
"crypto/sha256"
"fmt"
"math/rand"
"strings"
"time"
)
var vegeRand *rand.Rand
func init() {
vegeRand = rand.New(rand.NewSource(time.Now().UnixNano()))
}
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
const (
letterIdxBits = 6 // 6 bits to represent a letter index
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
)
func RandStringMask(n int) string {
b := new(strings.Builder)
b.Grow(n)
// A vegeRand.Int63() generates 63 random bits, enough for letterIdxMax letters!
for i, cache, remain := n-1, vegeRand.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = vegeRand.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
b.WriteByte(letterBytes[idx])
i--
}
cache >>= letterIdxBits
remain--
}
return b.String()
}
func RandBytesMask(n int) []byte {
b := make([]byte, n)
// A vegeRand.Int63() generates 63 random bits, enough for letterIdxMax letters!
for i, cache, remain := n-1, vegeRand.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = vegeRand.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
b[i] = letterBytes[idx]
i--
}
cache >>= letterIdxBits
remain--
}
return b
}
const codeBytes = "0123456789"
func RandCodeMask(n int) string {
b := new(strings.Builder)
b.Grow(n)
// A vegeRand.Int63() generates 63 random bits, enough for letterIdxMax letters!
for i, cache, remain := n-1, vegeRand.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = vegeRand.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(codeBytes) {
b.WriteByte(codeBytes[idx])
i--
}
cache >>= letterIdxBits
remain--
}
return b.String()
}
const idBytes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
func RandIdMask(n int) string {
b := new(strings.Builder)
b.Grow(n)
// A vegeRand.Int63() generates 63 random bits, enough for letterIdxMax letters!
for i, cache, remain := n-1, vegeRand.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = vegeRand.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(idBytes) {
b.WriteByte(idBytes[idx])
i--
}
cache >>= letterIdxBits
remain--
}
return b.String()
}
func RandSelfDefMask(n int, bs string) string {
b := new(strings.Builder)
b.Grow(n)
// A vegeRand.Int63() generates 63 random bits, enough for letterIdxMax letters!
for i, cache, remain := n-1, vegeRand.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = vegeRand.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(bs) {
b.WriteByte(bs[idx])
i--
}
cache >>= letterIdxBits
remain--
}
return b.String()
}
// HmacHashWithSalt
// hmac sha2 and salt make hash
func HmacHashWithSalt(ps, salt string) string {
mac := hmac.New(sha256.New, []byte(ps))
mac.Write([]byte(salt))
hs := mac.Sum(nil)
return fmt.Sprintf("%x", hs)
}
// CheckBySalt
// check HmacHashWithSalt
func CheckBySalt(check, hash, salt string) bool {
expectedMAC := HmacHashWithSalt(check, salt)
return hmac.Equal([]byte(hash), []byte(expectedMAC))
}