Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
163 lines (142 sloc) 6.16 KB
package main
import (
"fmt"
"strconv"
"os"
"bufio"
)
type inspectInterface interface {}
func inspect(v inspectInterface) string {
r := ""
switch t := v.(type) {
default:
r = fmt.Sprintf("%v", v)
case string:
r = strconv.Quote(v.(string))
}
return r
}
func p(s inspectInterface) {
fmt.Println(inspect(s))
}
var doubleDigits = []uint8{0, 2, 4, 6, 8, 1, 3, 5, 7, 9}
type Luhn struct{}
func NewLuhn() *Luhn {
return &Luhn{}
}
func (Luhn) TestIt(a *[]byte, startAt int, maxLen int) bool {
total := uint8(0)
doubleDigit := false
for i := startAt + maxLen - 1; i >= startAt; i-- {
if doubleDigit {
total += doubleDigits[(*a)[i]]
} else {
total += (*a)[i]
}
doubleDigit = !doubleDigit
}
return total % 10 == 0
}
func (lu Luhn) Mask(s string) string {
var masked []byte
i := 0
digitCount := 0
maskOffset := -1
digits := []byte{}
len := len(s)
for i < len {
c := s[i]
if c >= 48 && c <= 57 { //between 0 and 9
digitCount += 1
digits = append(digits, c - 48)
if digitCount >= 14 {
theLen := 16
if digitCount < 16 { theLen = digitCount }
for ; theLen >= 14; theLen-- {
startAt := digitCount - theLen
if lu.TestIt(&digits, startAt, theLen) {
if masked == nil { masked = []byte(s) }
j := i
for maskLen := theLen; maskLen > 0 && j > maskOffset; {
mc := s[j]
if mc >= 48 && mc <= 57 { //between 0 and 9
masked[j] = 88 //'X'
maskLen -= 1
}
j -= 1
}
if i == 16 { maskOffset = i }
}
}
}
} else if c != 45 && c != 32 { //not - or space
if digitCount > 0 {
digitCount = 0
digits = []byte{}
}
}
i += 1
}
if masked != nil {
return string(masked)
}
return s
}
func sampleTest() {
a := []string{
"56613959932537",
"508733740140655",
"6853371389452376",
"49536290423965",
"306903975081421",
"6045055735309820",
"5872120460121",
"99929316122852072",
"0003813474535310",
"0114762758182750",
"9875610591081018250321",
"1256613959932537",
"4352 7211 4223 5131",
"7288-8379-3639-2755",
"java.lang.FakeException: 7230 3161 3748 4124 is a card #.",
"4111 1111 1111 111 doesn't have enough digits.",
"56613959932535089 has too many digits.",
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"5212843322137064296101908962963186202766554788983704435814703972605368416396055678877682488862234546927406211307521284332213706429610190896296318620276655478898370443581470397260536841639605567887768248886223454692740621130752128433221370642961019089629631862027665547889837044358147039726053684163960556788776824888622345469274062113075212843322137064296101908962963186202766554788983704435814703972605368416396055678877682488862234546927406211307521284332213706429610190896296318620276655478898370443581470397260536841639605567887768248886223454692740621130752128433221370642961019089629631862027665547889837044358147039726053684163960556788776824888622345469274062113075212843322137064296101908962963186202766554788983704435814703972605368416396055678877682488862234546927406211307521284332213706429610190896296318620276655478898370443581470397260536841639605567887768248886223454692740621130752128433221370642961019089629631862027665547889837044358147039726053684163960556788776824888622345469274",
"5451496852732996063216961135925002811586537152199011985874232493633063047918301881385483284586533476253043731721256291647129524137724321728426184434461211703740649863341542579718271551110706936707319896126135944655506777360650140073402696573847382312143994860950153547889826890506187544774005026327396239056283010290981735778560515623251759619833225650753259593746554508212002384743816147220901767420098517594528110348433559626620298669171000062321471778438988210772771125375553564585320157635817785646893772472227467874437527001732836456864256454316370375336790286880557855773092293464498480234269658315323895080609167720971257548045968322939533404152970558280322501801922337656360557826932953501196791996392141409716242024358132638936168824328539157595191336754405365165167449323818836023303930252215414173373588852488517005006682091203000533131570369087503070508446066122223326556254899598241462739083519446495374791938334509806165682356091342533772992235963750210739883141610937988149208758059239",
}
luhn := NewLuhn()
for _, s := range a {
fmt.Println(luhn.Mask(s))
}
}
func (lu Luhn) TapStdin() {
nRepeats := 1
if len(os.Args) > 1 { nRepeats, _ = strconv.Atoi(os.Args[1]) }
ios, _ := bufio.NewReaderSize(os.Stdin, 16384)
bw, _ := bufio.NewWriterSize(os.Stdout, 16384)
if nRepeats > 1 {
s, err := ios.ReadSlice('\n')
lines := []string{}
for err == nil {
lines = append(lines, string(s))
s, err = ios.ReadSlice('\n')
}
for i := 0; i < nRepeats; i++ {
for _, s := range lines {
bw.WriteString(lu.Mask(s))
}
}
} else {
s, err := ios.ReadSlice('\n')
for err == nil {
bw.WriteString(lu.Mask(string(s)))
s, err = ios.ReadSlice('\n')
}
}
bw.Flush()
}
func main() {
// sampleTest()
(NewLuhn()).TapStdin()
}
Something went wrong with that request. Please try again.