2020-08-30 00:46:11 +03:00
|
|
|
package pin
|
|
|
|
|
2024-01-23 18:20:00 +03:00
|
|
|
import (
|
2020-08-30 00:46:11 +03:00
|
|
|
"fmt"
|
2024-01-23 18:20:00 +03:00
|
|
|
//"strconv"
|
|
|
|
//"log"
|
2024-09-22 16:40:58 +03:00
|
|
|
"io"
|
2024-01-23 18:20:00 +03:00
|
|
|
"os"
|
2024-09-22 16:40:58 +03:00
|
|
|
|
|
|
|
"surdeus.su/core/cli/mtool"
|
2020-08-30 00:46:11 +03:00
|
|
|
)
|
|
|
|
|
2024-01-23 18:20:00 +03:00
|
|
|
var (
|
2020-08-30 00:46:11 +03:00
|
|
|
delim rune = '\n'
|
2024-09-23 01:06:50 +03:00
|
|
|
Tool = mtool.T("pin").Func(Run).Desc(
|
2024-01-23 18:20:00 +03:00
|
|
|
"print all the possible PIN combinations made of custom characters",
|
|
|
|
).Usage(
|
2024-09-21 01:38:28 +03:00
|
|
|
"",
|
2024-01-23 18:20:00 +03:00
|
|
|
)
|
2020-08-30 00:46:11 +03:00
|
|
|
)
|
|
|
|
|
2024-01-23 18:20:00 +03:00
|
|
|
func Pow(x, p int) int {
|
2024-09-22 16:40:58 +03:00
|
|
|
ret := 1
|
2024-09-23 01:06:50 +03:00
|
|
|
for i := 0; i < p; i++ {
|
2020-08-30 00:46:11 +03:00
|
|
|
ret *= x
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
2024-09-22 16:40:58 +03:00
|
|
|
func GetPin(chars []rune, length int, i int) string {
|
2020-08-30 00:46:11 +03:00
|
|
|
ret := ""
|
2024-09-22 16:40:58 +03:00
|
|
|
slen := len(chars)
|
2024-09-23 01:06:50 +03:00
|
|
|
for j := 0; j < length; j++ {
|
|
|
|
ret = string(chars[(i/Pow(slen, j))%slen]) + ret
|
2020-08-30 00:46:11 +03:00
|
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
2024-09-22 16:40:58 +03:00
|
|
|
func FprintPins(
|
|
|
|
output io.Writer,
|
|
|
|
chars []rune,
|
|
|
|
length int,
|
2024-09-23 01:06:50 +03:00
|
|
|
maxReps int,
|
2024-09-22 16:40:58 +03:00
|
|
|
) {
|
|
|
|
n := Pow(len(chars), length)
|
2024-09-23 01:06:50 +03:00
|
|
|
for i := 0; i < n; i++ {
|
2024-09-22 16:40:58 +03:00
|
|
|
pin := GetPin(chars, length, i)
|
2024-09-23 01:06:50 +03:00
|
|
|
if Fits([]rune(pin), chars, maxReps) {
|
2024-09-22 16:40:58 +03:00
|
|
|
fmt.Fprintln(
|
|
|
|
output,
|
|
|
|
GetPin(chars, length, i),
|
|
|
|
)
|
2022-05-19 05:21:26 +03:00
|
|
|
}
|
2020-08-30 00:46:11 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-22 16:40:58 +03:00
|
|
|
func Fits(s []rune, chrs []rune, maxReps int) bool {
|
2022-05-19 05:21:26 +03:00
|
|
|
a := make([]int, len(chrs))
|
|
|
|
for i, v1 := range chrs {
|
|
|
|
for _, v2 := range s {
|
|
|
|
if v1 == v2 {
|
|
|
|
a[i]++
|
2024-09-22 16:40:58 +03:00
|
|
|
if a[i] > maxReps {
|
2022-05-19 05:21:26 +03:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2024-09-22 16:40:58 +03:00
|
|
|
func Run(
|
|
|
|
flags *mtool.Flags,
|
|
|
|
) {
|
2024-09-23 01:06:50 +03:00
|
|
|
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)
|
2024-09-22 16:40:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func CustomRun(
|
|
|
|
input io.Reader,
|
|
|
|
output io.Writer,
|
|
|
|
flags *mtool.Flags,
|
|
|
|
) {
|
2024-01-23 18:20:00 +03:00
|
|
|
var (
|
2024-09-23 01:06:50 +03:00
|
|
|
length int
|
|
|
|
rFlag bool
|
|
|
|
mFlag bool
|
2024-09-22 16:40:58 +03:00
|
|
|
minLength int
|
2024-09-23 01:06:50 +03:00
|
|
|
maxReps int
|
2024-01-23 18:20:00 +03:00
|
|
|
)
|
2024-09-21 01:38:28 +03:00
|
|
|
var (
|
2024-09-22 16:40:58 +03:00
|
|
|
charsString string
|
2024-09-23 01:06:50 +03:00
|
|
|
chrs []rune
|
2024-09-21 01:38:28 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
flags.StringVar(
|
2024-09-22 16:40:58 +03:00
|
|
|
&charsString,
|
2024-09-21 01:38:28 +03:00
|
|
|
"c",
|
|
|
|
"0123456789",
|
|
|
|
"character set for substitution",
|
|
|
|
"COMBO_CHARS",
|
|
|
|
)
|
2024-01-23 18:20:00 +03:00
|
|
|
flags.IntVar(
|
2024-09-23 01:06:50 +03:00
|
|
|
&minLength, "min-len", 4,
|
2024-01-23 18:20:00 +03:00
|
|
|
"min length of the output pins",
|
|
|
|
)
|
|
|
|
flags.BoolVar(
|
2024-09-22 16:40:58 +03:00
|
|
|
&mFlag, "m", false,
|
2024-09-23 01:06:50 +03:00
|
|
|
"set the '-min-len' flag value to 1 (overrides the '-min-len')",
|
2022-05-19 05:21:26 +03:00
|
|
|
)
|
2024-01-23 18:20:00 +03:00
|
|
|
flags.IntVar(
|
2024-09-23 01:06:50 +03:00
|
|
|
&length, "max-len", 0,
|
2024-01-23 18:20:00 +03:00
|
|
|
"max length of the output pins",
|
|
|
|
)
|
|
|
|
|
2024-09-23 01:06:50 +03:00
|
|
|
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")
|
2024-01-23 18:20:00 +03:00
|
|
|
|
2024-09-21 01:38:28 +03:00
|
|
|
_ = flags.Parse()
|
2022-05-19 05:21:26 +03:00
|
|
|
|
2024-09-21 01:38:28 +03:00
|
|
|
/*if len(args) == 0 {
|
2024-01-23 18:20:00 +03:00
|
|
|
flags.Usage()
|
|
|
|
os.Exit(1)
|
2024-09-21 01:38:28 +03:00
|
|
|
}*/
|
2022-05-19 05:21:26 +03:00
|
|
|
|
2024-09-22 16:40:58 +03:00
|
|
|
chrs = []rune(charsString)
|
2020-08-30 00:46:11 +03:00
|
|
|
|
2024-01-23 18:20:00 +03:00
|
|
|
if length == 0 {
|
2024-09-21 01:38:28 +03:00
|
|
|
length = 4
|
2020-08-30 00:46:11 +03:00
|
|
|
}
|
|
|
|
|
2024-09-22 16:40:58 +03:00
|
|
|
if mFlag {
|
|
|
|
minLength = 1
|
2022-05-06 19:26:28 +03:00
|
|
|
}
|
|
|
|
|
2024-01-23 18:20:00 +03:00
|
|
|
if rFlag {
|
2024-09-22 16:40:58 +03:00
|
|
|
maxReps = len(chrs)
|
2024-01-23 18:20:00 +03:00
|
|
|
}
|
|
|
|
|
2024-09-22 16:40:58 +03:00
|
|
|
if minLength != 0 {
|
|
|
|
if minLength > length {
|
2024-01-23 18:20:00 +03:00
|
|
|
flags.Usage()
|
|
|
|
os.Exit(1)
|
2022-05-06 19:26:28 +03:00
|
|
|
}
|
2024-09-23 01:06:50 +03:00
|
|
|
for i := minLength; i <= length; i++ {
|
|
|
|
FprintPins(output, chrs, i, maxReps)
|
2022-05-06 19:26:28 +03:00
|
|
|
}
|
|
|
|
} else {
|
2024-09-23 01:06:50 +03:00
|
|
|
FprintPins(output, chrs, length, maxReps)
|
2022-05-06 19:26:28 +03:00
|
|
|
}
|
2020-08-30 00:46:11 +03:00
|
|
|
|
|
|
|
}
|