combo/pin/pin.go

164 lines
2.5 KiB
Go
Raw Normal View History

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'
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-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
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)
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,
maxReps int,
2024-09-22 16:40:58 +03:00
) {
n := Pow(len(chars), length)
for i := 0; i < n; i++ {
2024-09-22 16:40:58 +03:00
pin := GetPin(chars, length, i)
if Fits([]rune(pin), chars, maxReps) {
2024-09-22 16:40:58 +03:00
fmt.Fprintln(
output,
GetPin(chars, length, i),
)
}
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 {
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 {
return false
}
}
}
}
return true
}
2024-09-22 16:40:58 +03:00
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)
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 (
length int
rFlag bool
mFlag bool
2024-09-22 16:40:58 +03:00
minLength int
maxReps int
2024-01-23 18:20:00 +03:00
)
var (
2024-09-22 16:40:58 +03:00
charsString string
chrs []rune
)
flags.StringVar(
2024-09-22 16:40:58 +03:00
&charsString,
"c",
"0123456789",
"character set for substitution",
"COMBO_CHARS",
)
2024-01-23 18:20:00 +03:00
flags.IntVar(
&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,
"set the '-min-len' flag value to 1 (overrides the '-min-len')",
)
2024-01-23 18:20:00 +03:00
flags.IntVar(
&length, "max-len", 0,
2024-01-23 18:20:00 +03:00
"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")
2024-01-23 18:20:00 +03:00
_ = flags.Parse()
/*if len(args) == 0 {
2024-01-23 18:20:00 +03:00
flags.Usage()
os.Exit(1)
}*/
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 {
length = 4
2020-08-30 00:46:11 +03:00
}
2024-09-22 16:40:58 +03:00
if mFlag {
minLength = 1
}
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)
}
for i := minLength; i <= length; i++ {
FprintPins(output, chrs, i, maxReps)
}
} else {
FprintPins(output, chrs, length, maxReps)
}
2020-08-30 00:46:11 +03:00
}