diff --git a/CHANGELOG.md b/CHANGELOG.md
index 22b9f19..2e1c5e3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# go-utils
+
+## [v1.4.0] - 2020-06-11
+### New Features
+- create GenerateRandomAlphanumeric
+
+
## [v1.3.1] - 2020-04-02
### Fixes
@@ -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
diff --git a/rand.go b/rand.go
index 52da818..b61be00 100644
--- a/rand.go
+++ b/rand.go
@@ -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<= 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()
+}
diff --git a/rand_test.go b/rand_test.go
new file mode 100644
index 0000000..5a619b1
--- /dev/null
+++ b/rand_test.go
@@ -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)
+ }
+}