diff --git a/docs/strings.md b/docs/strings.md index 01765eeb..9dcaa488 100644 --- a/docs/strings.md +++ b/docs/strings.md @@ -159,6 +159,25 @@ initials "First Try" The above returns `FT` +## cryptoRandAlphaNum, cryptoRandAlpha, cryptoRandNumeric, and cryptoRandAscii + +These four functions generate cryptographically secure (uses ```crypto/rand```) +random strings, but with different base character sets. They should be used for +generating random strings to be used for security purposes: + +- `cryptoRandAlphaNum` uses `0-9a-zA-Z` +- `cryptoRandAlpha` uses `a-zA-Z` +- `cryptoRandNumeric` uses `0-9` +- `cryptoRandAscii` uses all printable ASCII characters + +Each of them takes one parameter: the integer length of the string. + +``` +cryptoRandNumeric 30 +``` + +The above will produce a cryptographically secure random string with thirty digits. + ## randAlphaNum, randAlpha, randNumeric, and randAscii These four functions generate random strings, but with different base character diff --git a/functions.go b/functions.go index 264352d4..eec51842 100644 --- a/functions.go +++ b/functions.go @@ -10,7 +10,7 @@ import ( ttemplate "text/template" "time" - util "github.com/aokoli/goutils" + util "github.com/Masterminds/goutils" "github.com/huandu/xstrings" ) @@ -75,6 +75,10 @@ var nonhermeticFunctions = []string{ "dateModify", // Strings + "cryptoRandAlphaNum", + "cryptoRandAlpha", + "cryptoRandAscii", + "cryptoRandNumeric", "randAlphaNum", "randAlpha", "randAscii", @@ -121,6 +125,10 @@ var genericMap = map[string]interface{}{ "trimPrefix": func(a, b string) string { return strings.TrimPrefix(b, a) }, "nospace": util.DeleteWhiteSpace, "initials": initials, + "cryptoRandAlphaNum": cryptoRandAlphaNumeric, + "cryptoRandAlpha": cryptoRandAlpha, + "cryptoRandAscii": cryptoRandAscii, + "cryptoRandNumeric": cryptoRandNumeric, "randAlphaNum": randAlphaNumeric, "randAlpha": randAlpha, "randAscii": randAscii, diff --git a/functions_test.go b/functions_test.go index c593a5bc..737458c8 100644 --- a/functions_test.go +++ b/functions_test.go @@ -8,7 +8,7 @@ import ( "testing" "text/template" - "github.com/aokoli/goutils" + "github.com/Masterminds/goutils" "github.com/stretchr/testify/assert" ) diff --git a/glide.lock b/glide.lock index 4f417617..32908e4e 100644 --- a/glide.lock +++ b/glide.lock @@ -1,8 +1,6 @@ hash: 6a3f4f83c443958625ff1bafadd95c96d20d729f34e8e8c2fa72782194fc4807 updated: 2019-01-30T20:16:27.780177826+01:00 imports: -- name: github.com/aokoli/goutils - version: 9c37978a95bd5c709a15883b6242714ea6709e64 - name: github.com/google/uuid version: 064e2069ce9c359c118179501254f67d7d37ba24 - name: github.com/huandu/xstrings diff --git a/strings.go b/strings.go index 586e72c8..264cd92b 100644 --- a/strings.go +++ b/strings.go @@ -8,7 +8,7 @@ import ( "strconv" "strings" - util "github.com/aokoli/goutils" + util "github.com/Masterminds/goutils" ) func base64encode(v string) string { @@ -55,6 +55,26 @@ func initials(s string) string { return util.Initials(s) } +func cryptoRandAlphaNumeric(count int) string { + r, _ := util.CryptoRandomAlphaNumeric(count) + return r +} + +func cryptoRandAlpha(count int) string { + r, _ := util.CryptoRandomAlphabetic(count) + return r +} + +func cryptoRandAscii(count int) string { + r, _ := util.CryptoRandomAscii(count) + return r +} + +func cryptoRandNumeric(count int) string { + r, _ := util.CryptoRandomNumeric(count) + return r +} + func randAlphaNumeric(count int) string { // It is not possible, it appears, to actually generate an error here. r, _ := util.RandomAlphaNumeric(count) diff --git a/strings_test.go b/strings_test.go index a795f71e..606fb26e 100644 --- a/strings_test.go +++ b/strings_test.go @@ -6,8 +6,9 @@ import ( "fmt" "math/rand" "testing" + "unicode/utf8" - "github.com/aokoli/goutils" + "github.com/Masterminds/goutils" "github.com/stretchr/testify/assert" ) @@ -189,6 +190,30 @@ func TestGoutils(t *testing.T) { } } +func TestCryptoRandom(t *testing.T) { + // These tests have no predictable character sequence. No checks for exact string output are necessary. + + // {{cryptoRandAlphaNum 5}} should yield five random characters + if x, _ := runRaw(`{{cryptoRandAlphaNum 5}}`, nil); utf8.RuneCountInString(x) != 5 { + t.Errorf("String should be 5 characters; string was %v characters", utf8.RuneCountInString(x)) + } + + // {{cryptoRandAlpha 5}} should yield five random characters + if x, _ := runRaw(`{{cryptoRandAlpha 5}}`, nil); utf8.RuneCountInString(x) != 5 { + t.Errorf("String should be 5 characters; string was %v characters", utf8.RuneCountInString(x)) + } + + // {{cryptoRandAscii 5}} should yield five random characters + if x, _ := runRaw(`{{cryptoRandAscii 5}}`, nil); utf8.RuneCountInString(x) != 5 { + t.Errorf("String should be 5 characters; string was %v characters", utf8.RuneCountInString(x)) + } + + // {{cryptoRandNumeric 5}} should yield five random characters + if x, _ := runRaw(`{{cryptoRandNumeric 5}}`, nil); utf8.RuneCountInString(x) != 5 { + t.Errorf("String should be 5 characters; string was %v characters", utf8.RuneCountInString(x)) + } +} + func TestRandom(t *testing.T) { // One of the things I love about Go: goutils.RANDOM = rand.New(rand.NewSource(1))