package gofakeit // Username will generate a random username based upon picking a random lastname and random numbers at the end func Username() string { return username(GlobalFaker) } // Username will generate a random username based upon picking a random lastname and random numbers at the end func (f *Faker) Username() string { return username(f) } func username(f *Faker) string { username := getRandValue(f, []string{"auth", "username"}) username, err := generate(f, username) if err != nil { return username // fallback to raw template if generation fails } return username } // Password will generate a random password. // Minimum number length of 5 if less than. func Password(lower bool, upper bool, numeric bool, special bool, space bool, num int) string { return password(GlobalFaker, lower, upper, numeric, special, space, num) } // Password will generate a random password. // Minimum number length of 5 if less than. func (f *Faker) Password(lower bool, upper bool, numeric bool, special bool, space bool, num int) string { return password(f, lower, upper, numeric, special, space, num) } func password(f *Faker, lower bool, upper bool, numeric bool, special bool, space bool, num int) string { // Make sure the num minimum is at least 5 if num < 5 { num = 5 } type charGroup struct { chars string weight int isSpace bool } defaultNonSpace := [...]charGroup{ {chars: lowerStr, weight: 4}, {chars: upperStr, weight: 4}, {chars: numericStr, weight: 3}, } const defaultNonSpaceWeight = 4 + 4 + 3 var ( activeBuf [5]charGroup nonSpaceBuf [5]charGroup active []charGroup totalWeight int nonSpace []charGroup nonSpaceWeight int ) appendGroup := func(enabled bool, chars string, weight int, isSpace bool) { if !enabled { return } active = append(active, charGroup{chars: chars, weight: weight, isSpace: isSpace}) totalWeight += weight if !isSpace { nonSpace = append(nonSpace, charGroup{chars: chars, weight: weight}) nonSpaceWeight += weight } } active = activeBuf[:0] nonSpace = nonSpaceBuf[:0] appendGroup(lower, lowerStr, 4, false) appendGroup(upper, upperStr, 4, false) appendGroup(numeric, numericStr, 3, false) appendGroup(special, specialSafeStr, 2, false) appendGroup(space, spaceStr, 1, true) // If no items are selected then default to lower, upper, numeric if len(active) == 0 { active = defaultNonSpace[:] totalWeight = defaultNonSpaceWeight nonSpace = active nonSpaceWeight = totalWeight } else if nonSpaceWeight == 0 { // No non-space characters were added (only spaces); fall back to defaults. nonSpace = defaultNonSpace[:] nonSpaceWeight = defaultNonSpaceWeight } draw := func(groups []charGroup, total int) byte { if total <= 0 { groups = defaultNonSpace[:] total = defaultNonSpaceWeight } r := f.IntN(total) for _, g := range groups { if r < g.weight { return g.chars[f.IntN(len(g.chars))] } r -= g.weight } // Should never be reached, but fall back to the last group just in case. g := groups[len(groups)-1] return g.chars[f.IntN(len(g.chars))] } // Create byte slice b := make([]byte, num) // Guarantee at least one character from each enabled non-space group so // the password always satisfies the requested character-set criteria. for i, g := range nonSpace { b[i] = g.chars[f.IntN(len(g.chars))] } // Fill the remaining positions randomly from all active groups. for i := len(nonSpace); i < num; i++ { b[i] = draw(active, totalWeight) } // Shuffle bytes for i := range b { j := f.IntN(i + 1) b[i], b[j] = b[j], b[i] } // Replace first or last character if it's a space, and other options are available if b[0] == ' ' { b[0] = draw(nonSpace, nonSpaceWeight) } if b[len(b)-1] == ' ' { b[len(b)-1] = draw(nonSpace, nonSpaceWeight) } return string(b) } func addAuthLookup() { AddFuncLookup("username", Info{ Display: "Username", Category: "auth", Description: "Unique identifier assigned to a user for accessing an account or system", Example: "Daniel1364", Output: "string", Aliases: []string{ "user name", "login name", "account username", "account login", "screen name", "user handle", }, Keywords: []string{ "login", "handle", "userid", "screenname", "user", "account", "credential", "signin", "alias", "profile", "uid", }, Generate: func(f *Faker, m *MapParams, info *Info) (any, error) { return username(f), nil }, }) AddFuncLookup("password", Info{ Display: "Password", Category: "auth", Description: "Secret word or phrase used to authenticate access to a system or account", Example: "EEP+wwpk 4lU-eHNXlJZ4n K9%v&TZ9e", Output: "string", Aliases: []string{ "user password", "account password", "login password", "secret phrase", "auth secret", }, Keywords: []string{ "passphrase", "pwd", "secret", "credential", "authentication", "auth", "security", "signin", "login", "access", "key", "token", "hash", "encryption", }, Params: []Param{ {Field: "lower", Display: "Lower", Type: "bool", Default: "true", Description: "Whether or not to add lower case characters"}, {Field: "upper", Display: "Upper", Type: "bool", Default: "true", Description: "Whether or not to add upper case characters"}, {Field: "numeric", Display: "Numeric", Type: "bool", Default: "true", Description: "Whether or not to add numeric characters"}, {Field: "special", Display: "Special", Type: "bool", Default: "true", Description: "Whether or not to add special characters"}, {Field: "space", Display: "Space", Type: "bool", Default: "false", Description: "Whether or not to add spaces"}, {Field: "length", Display: "Length", Type: "int", Default: "12", Description: "Number of characters in password"}, }, Generate: func(f *Faker, m *MapParams, info *Info) (any, error) { lower, err := info.GetBool(m, "lower") if err != nil { return nil, err } upper, err := info.GetBool(m, "upper") if err != nil { return nil, err } numeric, err := info.GetBool(m, "numeric") if err != nil { return nil, err } special, err := info.GetBool(m, "special") if err != nil { return nil, err } space, err := info.GetBool(m, "space") if err != nil { return nil, err } length, err := info.GetInt(m, "length") if err != nil { return nil, err } return password(f, lower, upper, numeric, special, space, length), nil }, }) }