Skip to content

Commit

Permalink
Merge pull request #8 from riskimidiw/feature/random-string
Browse files Browse the repository at this point in the history
feature: create GenerateRandomAlphanumeric
  • Loading branch information
aslamhadi authored Jun 11, 2020
2 parents e009ad9 + ff14ef4 commit c562a67
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 3 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# go-utils

<a name="v1.4.0"></a>
## [v1.4.0] - 2020-06-11
### New Features
- create GenerateRandomAlphanumeric


<a name="v1.3.1"></a>
## [v1.3.1] - 2020-04-02
### Fixes
Expand Down Expand Up @@ -33,7 +39,8 @@
- init go-utils


[Unreleased]: https://github.com/kumparan/kumnats/compare/v1.3.1...HEAD
[Unreleased]: https://github.com/kumparan/kumnats/compare/v1.4.0...HEAD
[v1.4.0]: https://github.com/kumparan/kumnats/compare/v1.3.1...v1.4.0
[v1.3.1]: https://github.com/kumparan/kumnats/compare/v1.3.0...v1.3.1
[v1.3.0]: https://github.com/kumparan/kumnats/compare/v1.2.0...v1.3.0
[v1.2.0]: https://github.com/kumparan/kumnats/compare/v1.1.1...v1.2.0
Expand Down
38 changes: 36 additions & 2 deletions rand.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
package utils

import (
"crypto/rand"
cryptoRand "crypto/rand"
"encoding/base64"
mathRand "math/rand"
"strings"
"time"
)

const (
letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
letterIdxBits = 6
letterIdxMask = 1<<letterIdxBits - 1
letterIdxMax = 63 / letterIdxBits
)

var (
src = mathRand.NewSource(time.Now().UnixNano())
)

// GenerateRandomBytes adapted from https://elithrar.github.io/article/generating-secure-random-numbers-crypto-rand/
Expand All @@ -12,7 +26,7 @@ import (
// case the caller should not continue.
func GenerateRandomBytes(n int) ([]byte, error) {
b := make([]byte, n)
_, err := rand.Read(b)
_, err := cryptoRand.Read(b)
// Note that err == nil only if we read len(b) bytes.
if err != nil {
return nil, err
Expand Down Expand Up @@ -46,3 +60,23 @@ func GenerateRandomStringURLSafe(n int) (string, error) {
b, err := GenerateRandomBytes(n)
return base64.URLEncoding.EncodeToString(b), err
}

// GenerateRandomAlphanumeric Generate random alphanumeric character adapted from
// https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-go
func GenerateRandomAlphanumeric(n int) string {
sb := strings.Builder{}
sb.Grow(n)
for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = src.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
sb.WriteByte(letterBytes[idx])
i--
}
cache >>= letterIdxBits
remain--
}

return sb.String()
}
21 changes: 21 additions & 0 deletions rand_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package utils

import "testing"

func BenchmarkGenerateRandomString(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _ = GenerateRandomString(100)
}
}

func BenchmarkGenerateRandomAlphanumeric(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = GenerateRandomAlphanumeric(100)
}
}

func BenchmarkGenerateRandomStringURLSafe(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _ = GenerateRandomStringURLSafe(100)
}
}

0 comments on commit c562a67

Please sign in to comment.