package pin import ( "fmt" //"strconv" //"log" "io" "os" "surdeus.su/core/cli/mtool" ) var ( delim rune = '\n' Tool = mtool.T("pin").Func(Run).Desc( "print all the possible PIN combinations made of custom characters", ).Usage( "", ) ) func Pow(x, p int) int { ret := 1 for i := 0; i < p; i++ { ret *= x } return ret } func GetPin(chars []rune, length int, i int) string { ret := "" slen := len(chars) for j := 0; j < length; j++ { ret = string(chars[(i/Pow(slen, j))%slen]) + ret } return ret } func FprintPins( output io.Writer, chars []rune, length int, maxReps int, ) { n := Pow(len(chars), length) for i := 0; i < n; i++ { pin := GetPin(chars, length, i) if Fits([]rune(pin), chars, maxReps) { fmt.Fprintln( output, GetPin(chars, length, i), ) } } } func Fits(s []rune, chrs []rune, maxReps int) bool { a := make([]int, len(chrs)) for i, v1 := range chrs { for _, v2 := range s { if v1 == v2 { a[i]++ if a[i] > maxReps { return false } } } } return true } func Run( flags *mtool.Flags, ) { cargs := flags.CustomArgs() if len(cargs) == 0 { CustomRun( os.Stdin, os.Stdout, flags, ) return } input := cargs[0].(io.Reader) output := cargs[1].(io.Writer) CustomRun(input, output, flags) } func CustomRun( input io.Reader, output io.Writer, flags *mtool.Flags, ) { var ( length int rFlag bool mFlag bool minLength int maxReps int ) var ( charsString string chrs []rune ) flags.StringVar( &charsString, "c", "0123456789", "character set for substitution", "COMBO_CHARS", ) flags.IntVar( &minLength, "min-len", 4, "min length of the output pins", ) flags.BoolVar( &mFlag, "m", false, "set the '-min-len' flag value to 1 (overrides the '-min-len')", ) flags.IntVar( &length, "max-len", 0, "max length of the output pins", ) flags.IntVar(&maxReps, "max-reps", 4, "max repeats of the rune.") flags.BoolVar(&rFlag, "r", false, "make the -max-reps value equal to the length of input chars") _ = flags.Parse() /*if len(args) == 0 { flags.Usage() os.Exit(1) }*/ chrs = []rune(charsString) if length == 0 { length = 4 } if mFlag { minLength = 1 } if rFlag { maxReps = len(chrs) } if minLength != 0 { if minLength > length { flags.Usage() os.Exit(1) } for i := minLength; i <= length; i++ { FprintPins(output, chrs, i, maxReps) } } else { FprintPins(output, chrs, length, maxReps) } }