Skip to content

Commit 513938f

Browse files
MrOzeanmatoous
authored andcommitted
Generate valid id for any custom alphabet (#15)
* Generate valid id for any alphabet * Add more complex examples
1 parent 7c5c131 commit 513938f

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

examples/simple_example.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,31 @@ import (
77
)
88

99
func main() {
10+
// Simple usage
1011
id, err := gonanoid.Nanoid()
1112
if err != nil {
1213
panic(err)
1314
}
1415
fmt.Printf("Generated id: %s\n", id)
16+
17+
// Custom length
18+
id, err = gonanoid.ID(5)
19+
if err != nil {
20+
panic(err)
21+
}
22+
fmt.Printf("Generated id: %s\n", id)
23+
24+
// Custom alphabet
25+
id, err = gonanoid.Generate("abcdefg", 10)
26+
if err != nil {
27+
panic(err)
28+
}
29+
fmt.Printf("Generated id: %s\n", id)
30+
31+
// Custom non ascii alphabet
32+
id, err = gonanoid.Generate("こちんにабдежиклмнは你好喂שלום😯😪🥱😌😛äöüß", 10)
33+
if err != nil {
34+
panic(err)
35+
}
36+
fmt.Printf("Generated id: %s\n", id)
1537
}

gonanoid.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import (
77
"math"
88
)
99

10+
var defaultAlphabet = []rune("_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
1011
const (
11-
defaultAlphabet = "_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" // len=64
1212
defaultSize = 21
1313
defaultMaskSize = 5
1414
)
@@ -34,7 +34,7 @@ func initMasks(params ...int) []uint {
3434
return masks
3535
}
3636

37-
func getMask(alphabet string, masks []uint) int {
37+
func getMask(alphabet []rune, masks []uint) int {
3838
for i := 0; i < len(masks); i++ {
3939
curr := int(masks[i])
4040
if curr >= len(alphabet)-1 {
@@ -45,7 +45,9 @@ func getMask(alphabet string, masks []uint) int {
4545
}
4646

4747
// Generate is a low-level function to change alphabet and ID size.
48-
func Generate(alphabet string, size int) (string, error) {
48+
func Generate(rawAlphabet string, size int) (string, error) {
49+
alphabet := []rune(rawAlphabet)
50+
4951
if len(alphabet) == 0 || len(alphabet) > 255 {
5052
return "", fmt.Errorf("alphabet must not empty and contain no more than 255 chars. Current len is %d", len(alphabet))
5153
}
@@ -58,7 +60,7 @@ func Generate(alphabet string, size int) (string, error) {
5860
ceilArg := 1.6 * float64(mask*size) / float64(len(alphabet))
5961
step := int(math.Ceil(ceilArg))
6062

61-
id := make([]byte, size)
63+
id := make([]rune, size)
6264
bytes := make([]byte, step)
6365
for j := 0; ; {
6466
_, err := BytesGenerator(bytes)
@@ -97,7 +99,7 @@ func Nanoid(param ...int) (string, error) {
9799
if err != nil {
98100
return "", err
99101
}
100-
id := make([]byte, size)
102+
id := make([]rune, size)
101103
for i := 0; i < size; i++ {
102104
id[i] = defaultAlphabet[bytes[i]&63]
103105
}

gonanoid_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func TestGeneratesURLFriendlyIDs(t *testing.T) {
2828
runeID := []rune(id)
2929

3030
for j := 0; j < len(runeID); j++ {
31-
res := strings.Contains(defaultAlphabet, string(runeID[j]))
31+
res := strings.Contains(string(defaultAlphabet), string(runeID[j]))
3232
if !res {
3333
t.Errorf(
3434
"GeneratesURLFriendlyIds error: char %v should be contained in %v",

0 commit comments

Comments
 (0)