mirror of
https://github.com/wneessen/apg-go.git
synced 2024-11-25 07:10:50 +01:00
Merge pull request #90 from wneessen/feature/70_group-password-characters-in-a-smart-phone-friendly-order
Add mobile-friendly character groupoing
This commit is contained in:
commit
b7b4073483
9 changed files with 142 additions and 19 deletions
54
README.md
54
README.md
|
@ -28,7 +28,7 @@ This section provides some examples on how to use apg-go for common password gen
|
||||||
|
|
||||||
### Login password for a website
|
### Login password for a website
|
||||||
```shell
|
```shell
|
||||||
$ apg -C -f 20 -n 1
|
$ apg-go -C -f 20 -n 1
|
||||||
Zq#lIY?=?J@4_\X@\xtf
|
Zq#lIY?=?J@4_\X@\xtf
|
||||||
```
|
```
|
||||||
**Note:** Nowadays 20 random characters are still considered secure for passwords. You might want to adjust
|
**Note:** Nowadays 20 random characters are still considered secure for passwords. You might want to adjust
|
||||||
|
@ -36,7 +36,7 @@ the `-f` parameter if you require a longer password.
|
||||||
|
|
||||||
### PIN generation
|
### PIN generation
|
||||||
```shell
|
```shell
|
||||||
$ apg -M lusN -f 6 -n 1
|
$ apg-go -M lusN -f 6 -n 1
|
||||||
952170
|
952170
|
||||||
```
|
```
|
||||||
**Note:** A code example on how to programatically build a PIN generator with apg-go, can be found
|
**Note:** A code example on how to programatically build a PIN generator with apg-go, can be found
|
||||||
|
@ -44,7 +44,7 @@ here: [pin-generator](example-code/pin-generator).
|
||||||
|
|
||||||
### Phone verification phrase (pronounceable)
|
### Phone verification phrase (pronounceable)
|
||||||
```shell
|
```shell
|
||||||
$ apg -a 0 -m 15 -x 15 -t -n 1
|
$ apg-go -a 0 -m 15 -x 15 -t -n 1
|
||||||
vEbErlaFryaNgyex (vE-bEr-la-Fry-aN-gy-ex)
|
vEbErlaFryaNgyex (vE-bEr-la-Fry-aN-gy-ex)
|
||||||
```
|
```
|
||||||
We generated a 15-character long pronounceable phrase with syllables output, for easy
|
We generated a 15-character long pronounceable phrase with syllables output, for easy
|
||||||
|
@ -52,7 +52,7 @@ use in e. g. a phone verification process.
|
||||||
|
|
||||||
### Cryptographic key for encryption
|
### Cryptographic key for encryption
|
||||||
```shell
|
```shell
|
||||||
$ apg -a 3 -f 32 -bh
|
$ apg-go -a 3 -f 32 -bh
|
||||||
```
|
```
|
||||||
We generated a 32 bytes/256 bits long fully binary secret that can be used i. e. as
|
We generated a 32 bytes/256 bits long fully binary secret that can be used i. e. as
|
||||||
encryption key for a AES-256 symmetric encryption. The output is represented in
|
encryption key for a AES-256 symmetric encryption. The output is represented in
|
||||||
|
@ -200,7 +200,7 @@ By default apg-go will generate 6 passwords, with a minimum length of 12 charact
|
||||||
maxiumum length of 20 characters. The generated password will use a character set constructed
|
maxiumum length of 20 characters. The generated password will use a character set constructed
|
||||||
from lower case, upper case and numeric characters.
|
from lower case, upper case and numeric characters.
|
||||||
```shell
|
```shell
|
||||||
$ ./apg-go
|
$ apg-go
|
||||||
R8rCC8bw5NvJmTUK2g
|
R8rCC8bw5NvJmTUK2g
|
||||||
cHB9qogTbfdzFgnH
|
cHB9qogTbfdzFgnH
|
||||||
hoHfpWAHHSNa4Q
|
hoHfpWAHHSNa4Q
|
||||||
|
@ -216,7 +216,7 @@ by setting the `-L` parameter. In addition you would set the `-S` parameter to e
|
||||||
characters. Finally the parameter `-n 1` is needed to keep apg-go from generating more than one
|
characters. Finally the parameter `-n 1` is needed to keep apg-go from generating more than one
|
||||||
password:
|
password:
|
||||||
```shell
|
```shell
|
||||||
$ ./apg-go -n 1 -L -S
|
$ apg-go -n 1 -L -S
|
||||||
XY7>}H@5U40&_A1*9I$
|
XY7>}H@5U40&_A1*9I$
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ parameters instead. The new style is all combined in the `-M` parameter. Using t
|
||||||
version of a parameter argument enables a feature, while the lower case version disabled it. The
|
version of a parameter argument enables a feature, while the lower case version disabled it. The
|
||||||
previous example could be represented like this in new style:
|
previous example could be represented like this in new style:
|
||||||
```shell
|
```shell
|
||||||
$ ./apg-go -n 1 -M lUSN
|
$ apg-go -n 1 -M lUSN
|
||||||
$</K?*|M)%8\U$5JA5~
|
$</K?*|M)%8\U$5JA5~
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ readability, you can set the `-H` parameter to toggle on the "human readable" fe
|
||||||
option is set, apg-go will avoid using any of the typical ambiguous characters in the generated
|
option is set, apg-go will avoid using any of the typical ambiguous characters in the generated
|
||||||
passwords.
|
passwords.
|
||||||
```shell
|
```shell
|
||||||
$ ./apg-go -n 1 -M LUSN -H
|
$ apg-go -n 1 -M LUSN -H
|
||||||
YpranThY3b6b5%\6ARx
|
YpranThY3b6b5%\6ARx
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ Let's assume, that for whatever reason, your generated password can never includ
|
||||||
this specific case, you can use the `-E` parameter to specify a list of characters that are to be excluded
|
this specific case, you can use the `-E` parameter to specify a list of characters that are to be excluded
|
||||||
from the password generation character set:
|
from the password generation character set:
|
||||||
```shell
|
```shell
|
||||||
$ ./apg-go -n 1 -M lUSN -H -E :
|
$ apg-go -n 1 -M lUSN -H -E :
|
||||||
~B2\%E_|\VV|/5C7EF=
|
~B2\%E_|\VV|/5C7EF=
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ parameter, apg-go will automatically default to the most secure settings. The co
|
||||||
basically implies that the password will use all available characters (lower case, upper case,
|
basically implies that the password will use all available characters (lower case, upper case,
|
||||||
numeric and special) and will make sure that human readability is disabled.
|
numeric and special) and will make sure that human readability is disabled.
|
||||||
```shell
|
```shell
|
||||||
$ ./apg-go -n 1 -C
|
$ apg-go -n 1 -C
|
||||||
{q6cvz9le5_fo"X7
|
{q6cvz9le5_fo"X7
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -268,13 +268,13 @@ want to be more specific, you can use the `-m` and `-x` parameters to override t
|
||||||
assume you want a single complex password with a length of exactly 32 characters you can do so by
|
assume you want a single complex password with a length of exactly 32 characters you can do so by
|
||||||
running:
|
running:
|
||||||
```shell
|
```shell
|
||||||
$ ./apg-go -n 1 -C -m 32 -x 32
|
$ apg-go -n 1 -C -m 32 -x 32
|
||||||
5lc&HBvx=!EUY*;'/t&>B|~sudhtyDBu
|
5lc&HBvx=!EUY*;'/t&>B|~sudhtyDBu
|
||||||
```
|
```
|
||||||
Alternatively, since v1.0.0 apg-go has the new `-f` flag, which allows to request a fixed length
|
Alternatively, since v1.0.0 apg-go has the new `-f` flag, which allows to request a fixed length
|
||||||
password. Instead of using `-m` and `-x` you can just use `-f 32` to get a 32 character long password:
|
password. Instead of using `-m` and `-x` you can just use `-f 32` to get a 32 character long password:
|
||||||
```shell
|
```shell
|
||||||
$ ./apg -n 1 -C -f 32
|
$ apg-go -n 1 -C -f 32
|
||||||
O"Q\d0zT'@(1f~%_56O*!q[!9:z[~\A*
|
O"Q\d0zT'@(1f~%_56O*!q[!9:z[~\A*
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ If you need to read out a password, it can be helpful to know the corresponding
|
||||||
the phonetic alphabet. By setting the `-l` parameter, agp-go will provide you with the phonetic spelling
|
the phonetic alphabet. By setting the `-l` parameter, agp-go will provide you with the phonetic spelling
|
||||||
(english language) of your newly created password:
|
(english language) of your newly created password:
|
||||||
```shell
|
```shell
|
||||||
$ ./apg-go -n 1 -M LUSN -H -E : -l
|
$ apg-go -n 1 -M LUSN -H -E : -l
|
||||||
fUTDKeFsU+zn3r= (foxtrot/Uniform/Tango/Delta/Kilo/echo/Foxtrot/sierra/Uniform/PLUS_SIGN/zulu/november/THREE/romeo/EQUAL_SIGN)
|
fUTDKeFsU+zn3r= (foxtrot/Uniform/Tango/Delta/Kilo/echo/Foxtrot/sierra/Uniform/PLUS_SIGN/zulu/november/THREE/romeo/EQUAL_SIGN)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -312,10 +312,10 @@ randomly generated passwords. It might also be helpful to run the pronoucable pa
|
||||||
"[HIBP](#have-i-been-pwned)" flag, so that each generated password is automatically checked against "Have I Been Pwned"
|
"[HIBP](#have-i-been-pwned)" flag, so that each generated password is automatically checked against "Have I Been Pwned"
|
||||||
database.
|
database.
|
||||||
```shell
|
```shell
|
||||||
$ ./apg-go -a 0 -n 1
|
$ apg-go -a 0 -n 1
|
||||||
KebrutinernMy
|
KebrutinernMy
|
||||||
|
|
||||||
$ ./apg-go -a 0 -n 1 -m 15 -x 15 -t
|
$ apg-go -a 0 -n 1 -m 15 -x 15 -t
|
||||||
pEnbocydrageT*En (pEn-bo-cy-dra-geT-ASTERISK-En)
|
pEnbocydrageT*En (pEn-bo-cy-dra-geT-ASTERISK-En)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -323,7 +323,7 @@ pEnbocydrageT*En (pEn-bo-cy-dra-geT-ASTERISK-En)
|
||||||
Sometimes you just want to quickly perform a simple, but random coinflip. Since v1.0.0 apg-go has a
|
Sometimes you just want to quickly perform a simple, but random coinflip. Since v1.0.0 apg-go has a
|
||||||
coinflip mode, which will return either "Heads" or "Tails". To use coinflip mode, use the `-a 2` argument:
|
coinflip mode, which will return either "Heads" or "Tails". To use coinflip mode, use the `-a 2` argument:
|
||||||
```shell
|
```shell
|
||||||
$ ./apg -n 10 -a 2
|
$ apg-go -n 10 -a 2
|
||||||
Tails
|
Tails
|
||||||
Tails
|
Tails
|
||||||
Heads
|
Heads
|
||||||
|
@ -348,12 +348,29 @@ This mode can be useful for example if you need to generate a AES-256 encryption
|
||||||
the default length for the secret generation in this mode, you can simply generate a secret key with
|
the default length for the secret generation in this mode, you can simply generate a secret key with
|
||||||
the following command:
|
the following command:
|
||||||
```shell
|
```shell
|
||||||
$ apg -a 3 -bh
|
$ apg-go -a 3 -bh
|
||||||
a1cdab8db365af3d70828b1fe43b7896190c157ad3f1ae2a0a1d52ec1628c6b5
|
a1cdab8db365af3d70828b1fe43b7896190c157ad3f1ae2a0a1d52ec1628c6b5
|
||||||
```
|
```
|
||||||
*For ease for readability we used the `-bh` flag, to instruct apg-go to output the secret in its
|
*For ease for readability we used the `-bh` flag, to instruct apg-go to output the secret in its
|
||||||
hexadecimal representation*
|
hexadecimal representation*
|
||||||
|
|
||||||
|
### Mobile-friendly character grouping
|
||||||
|
Since v1.2.0 apg-go supports grouping of characters in a mobile-friendly manner. Entering a random string
|
||||||
|
of characters with a smartphone touch screen is tedious and error prone due to the need to toggle keypads
|
||||||
|
to gain access to different character tables. For this reason, this feature groups the characters of the
|
||||||
|
generated password in "keypad-order". It does so by groupoing the characters into character groups. The
|
||||||
|
following precedense is used: Upper-case characters, lower-case characters, numeric values, any other
|
||||||
|
character.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```shell
|
||||||
|
$ apg-go -C -f 20 -n 1 -g
|
||||||
|
CETMPGGxuamj346!)>})
|
||||||
|
```
|
||||||
|
|
||||||
|
**Please note that this feature makes the generated passwords much more predictable and lowers the
|
||||||
|
entropy of the generated password. Please use this feature with caution**
|
||||||
|
|
||||||
### Minimum required characters
|
### Minimum required characters
|
||||||
Even though in apg-go you can select what kind of characters are used for the password generation, it is
|
Even though in apg-go you can select what kind of characters are used for the password generation, it is
|
||||||
not guaranteed, that if you request a password with a numeric value, that the generated password will
|
not guaranteed, that if you request a password with a numeric value, that the generated password will
|
||||||
|
@ -369,7 +386,7 @@ never being able to finish the job.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```shell
|
```shell
|
||||||
$ ./apg -n 10 -a 1 -M NLUs -f 20 -mN 3
|
$ apg-go -n 10 -a 1 -M NLUs -f 20 -mN 3
|
||||||
kqFG935E280LvTFUbJ4M
|
kqFG935E280LvTFUbJ4M
|
||||||
RVBJAI5tJ6hy6oWrNfXG
|
RVBJAI5tJ6hy6oWrNfXG
|
||||||
uy1IWBEoOQFyG66VrLqu
|
uy1IWBEoOQFyG66VrLqu
|
||||||
|
@ -409,6 +426,7 @@ _apg-go_ replicates most of the parameters of the original c-apg. Some parameter
|
||||||
- `-m <length>`: The minimum length of the password to be generated (Default: 12)
|
- `-m <length>`: The minimum length of the password to be generated (Default: 12)
|
||||||
- `-x <length>`: The maximum length of the password to be generated (Default: 20)
|
- `-x <length>`: The maximum length of the password to be generated (Default: 20)
|
||||||
- `-f <length>`: Fixed length of the password to be generated (Ignores -m and -x)
|
- `-f <length>`: Fixed length of the password to be generated (Ignores -m and -x)
|
||||||
|
- `-g`: When set, mobile-friendly character grouping will be enabled in Algo: 1 (Default: off)
|
||||||
- `-n <number of passwords>`: The amount of passwords to be generated (Default: 6)
|
- `-n <number of passwords>`: The amount of passwords to be generated (Default: 6)
|
||||||
- `-E <list of characters>`: Do not use the specified characters in generated passwords
|
- `-E <list of characters>`: Do not use the specified characters in generated passwords
|
||||||
- `-M <[LUNSHClunshc]>`: New style password parameters (upper-case enables, lower-case disables)
|
- `-M <[LUNSHClunshc]>`: New style password parameters (upper-case enables, lower-case disables)
|
||||||
|
|
2
apg.go
2
apg.go
|
@ -5,7 +5,7 @@
|
||||||
package apg
|
package apg
|
||||||
|
|
||||||
// VERSION represents the version string
|
// VERSION represents the version string
|
||||||
const VERSION = "1.1.0"
|
const VERSION = "1.2.0"
|
||||||
|
|
||||||
// Generator is the password generator type of the APG package
|
// Generator is the password generator type of the APG package
|
||||||
type Generator struct {
|
type Generator struct {
|
||||||
|
|
|
@ -36,6 +36,7 @@ func main() {
|
||||||
flag.BoolVar(&complexPass, "C", false, "")
|
flag.BoolVar(&complexPass, "C", false, "")
|
||||||
flag.StringVar(&config.ExcludeChars, "E", "", "")
|
flag.StringVar(&config.ExcludeChars, "E", "", "")
|
||||||
flag.Int64Var(&config.FixedLength, "f", 0, "")
|
flag.Int64Var(&config.FixedLength, "f", 0, "")
|
||||||
|
flag.BoolVar(&config.MobileGrouping, "g", false, "")
|
||||||
flag.BoolVar(&humanReadable, "H", false, "")
|
flag.BoolVar(&humanReadable, "H", false, "")
|
||||||
flag.BoolVar(&config.SpellPassword, "l", false, "")
|
flag.BoolVar(&config.SpellPassword, "l", false, "")
|
||||||
flag.BoolVar(&lowerCase, "L", false, "")
|
flag.BoolVar(&lowerCase, "L", false, "")
|
||||||
|
@ -225,6 +226,9 @@ Flags:
|
||||||
-f LENGTH Fixed length of the password to be generated (Ignores -m and -x)
|
-f LENGTH Fixed length of the password to be generated (Ignores -m and -x)
|
||||||
- Note: Due to the way the pronounceable password algorithm works,
|
- Note: Due to the way the pronounceable password algorithm works,
|
||||||
this setting might not always apply
|
this setting might not always apply
|
||||||
|
-g When set, mobile-friendly character grouping will be enabled in Algo: 1
|
||||||
|
- Note: Grouping characters in random passwords makes them much
|
||||||
|
more predictable and lowers the entropy of the generated password.
|
||||||
-n NUMBER Amount of password to be generated (Default: 6)
|
-n NUMBER Amount of password to be generated (Default: 6)
|
||||||
- Note: Does not apply to binary mode (Algo: 3)
|
- Note: Does not apply to binary mode (Algo: 3)
|
||||||
-E CHARS List of characters to be excluded in the generated password
|
-E CHARS List of characters to be excluded in the generated password
|
||||||
|
|
10
config.go
10
config.go
|
@ -53,6 +53,9 @@ type Config struct {
|
||||||
// MinUpperCase represents the minimum amount of upper-case characters that have
|
// MinUpperCase represents the minimum amount of upper-case characters that have
|
||||||
// to be part of the generated password
|
// to be part of the generated password
|
||||||
MinUpperCase int64
|
MinUpperCase int64
|
||||||
|
// MobileGrouping indicates if the generated password should be grouped in a
|
||||||
|
// mobile-friendly manner
|
||||||
|
MobileGrouping bool
|
||||||
// Mode holds the different character modes for the Random algorithm
|
// Mode holds the different character modes for the Random algorithm
|
||||||
Mode ModeMask
|
Mode ModeMask
|
||||||
// NumberPass sets the number of passwords that are generated
|
// NumberPass sets the number of passwords that are generated
|
||||||
|
@ -175,6 +178,13 @@ func WithMaxLength(length int64) Option {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithMobileGrouping enables the mobile-friendly character grouping for AlgoRandom
|
||||||
|
func WithMobileGrouping() Option {
|
||||||
|
return func(config *Config) {
|
||||||
|
config.MobileGrouping = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithModeMask overrides the default mode mask for the random algorithm
|
// WithModeMask overrides the default mode mask for the random algorithm
|
||||||
func WithModeMask(mask ModeMask) Option {
|
func WithModeMask(mask ModeMask) Option {
|
||||||
return func(config *Config) {
|
return func(config *Config) {
|
||||||
|
|
|
@ -184,6 +184,18 @@ func TestWithMinUppercase(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWithMobileGrouping(t *testing.T) {
|
||||||
|
c := NewConfig(WithMobileGrouping())
|
||||||
|
if c == nil {
|
||||||
|
t.Errorf("NewConfig(WithMobileGrouping()) failed, expected config pointer but got nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if c.MobileGrouping != true {
|
||||||
|
t.Errorf("NewConfig(WithMobileGrouping()) failed, expected: %t, got: %t",
|
||||||
|
true, c.MobileGrouping)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestWithModeMask(t *testing.T) {
|
func TestWithModeMask(t *testing.T) {
|
||||||
e := DefaultMode
|
e := DefaultMode
|
||||||
c := NewConfig(WithModeMask(e))
|
c := NewConfig(WithModeMask(e))
|
||||||
|
|
27
grouping.go
Normal file
27
grouping.go
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// SPDX-FileCopyrightText: 2021-2024 Winni Neessen <wn@neessen.dev>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package apg
|
||||||
|
|
||||||
|
import "unicode"
|
||||||
|
|
||||||
|
// GroupCharsForMobile takes a given string of characters and groups them in a mobile-friendly
|
||||||
|
// manner. The grouping is based on the following precedense: uppercase, lowercase, numbers
|
||||||
|
// and special characters. The grouped string is then returned.
|
||||||
|
func GroupCharsForMobile(chars string) string {
|
||||||
|
var uppers, lowers, numbers, others []rune
|
||||||
|
for _, char := range chars {
|
||||||
|
switch {
|
||||||
|
case unicode.IsUpper(char):
|
||||||
|
uppers = append(uppers, char)
|
||||||
|
case unicode.IsLower(char):
|
||||||
|
lowers = append(lowers, char)
|
||||||
|
case unicode.IsNumber(char):
|
||||||
|
numbers = append(numbers, char)
|
||||||
|
default:
|
||||||
|
others = append(others, char)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(uppers) + string(lowers) + string(numbers) + string(others)
|
||||||
|
}
|
28
grouping_test.go
Normal file
28
grouping_test.go
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// SPDX-FileCopyrightText: 2021-2024 Winni Neessen <wn@neessen.dev>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package apg
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestGroupCharacters(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
password string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{`PW: A1c9.Ba`, `A1c9.Ba`, `ABca19.`},
|
||||||
|
{`PW: PX4xDoiKrs,[egEAief{`, `PX4xDoiKrs,[egEAief{`, `PXDKEAxoirsegief4,[{`},
|
||||||
|
{`PW: *Z%C9d+PZYkD7D+{~r'w`, `*Z%C9d+PZYkD7D+{~r'w`, `ZCPZYDDdkrw97*%++{~'`},
|
||||||
|
{`PW: 4?r2YV:Abo&/z<3tJ*Z{`, `4?r2YV:Abo&/z<3tJ*Z{`, `YVAJZrbozt423?:&/<*{`},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
grouped := GroupCharsForMobile(tt.password)
|
||||||
|
if grouped != tt.want {
|
||||||
|
t.Errorf("GroupCharsForMobile() failed, expected: %s, got: %s", tt.want, grouped)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -354,6 +354,9 @@ func (g *Generator) generateRandom() (string, error) {
|
||||||
ok = g.checkMinimumRequirements(password)
|
ok = g.checkMinimumRequirements(password)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if g.config.MobileGrouping {
|
||||||
|
return GroupCharsForMobile(password), nil
|
||||||
|
}
|
||||||
return password, nil
|
return password, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -453,6 +453,27 @@ func TestGenerateRandom(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGenerateRandom_withGrouping(t *testing.T) {
|
||||||
|
config := NewConfig(WithAlgorithm(AlgoRandom), WithMinLength(1),
|
||||||
|
WithMaxLength(1), WithMobileGrouping())
|
||||||
|
config.MinNumeric = 1
|
||||||
|
generator := New(config)
|
||||||
|
pw, err := generator.generateRandom()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("generateRandom() failed: %s", err)
|
||||||
|
}
|
||||||
|
if len(pw) > 1 {
|
||||||
|
t.Errorf("expected password with length 1 but got: %d", len(pw))
|
||||||
|
}
|
||||||
|
n, err := strconv.Atoi(pw)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected password to be a number but got an error: %s", err)
|
||||||
|
}
|
||||||
|
if n < 0 || n > 9 {
|
||||||
|
t.Errorf("expected password to be a number between 0 and 9, got: %d", n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestGenerate(t *testing.T) {
|
func TestGenerate(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
Loading…
Reference in a new issue