package passage import ( "crypto/sha256" "strconv" ) const ( UseLower = 1 << iota UseUpper UseNumber UseSymbol ) type Passage struct { valids int length int pin string requireEachCharSet bool } func CreatePassage(pin string) *Passage { p := new(Passage) p.length = 20 p.valids = UseLower | UseUpper | UseNumber | UseSymbol p.pin = pin return p } func (p *Passage) SetRequireEachCharSet(r bool) { p.requireEachCharSet = r } func (p *Passage) EnableChars(which int) { p.valids |= which } func (p *Passage) DisableChars(which int) { p.valids ^= which } func (p *Passage) SetLength(length int) { p.length = length } func (p *Passage) GetLowers() string { return "abcdefghijklmnopqrstuvwxyz" } func (p *Passage) GetUppers() string { return "ABCDEFGHIJKLMNOPQRSTUVWXYZ" } func (p *Passage) GetNumbers() string { return "1234567890" } func (p *Passage) GetSymbols() string { return "~!@#$%^&*()[]{}|;:,<.>/?" } func (p *Passage) GetValidChars() string { validChars := "" if p.valids&UseLower == UseLower { validChars += p.GetLowers() } if p.valids&UseUpper == UseUpper { validChars += p.GetUppers() } if p.valids&UseNumber == UseNumber { validChars += p.GetNumbers() } if p.valids&UseSymbol == UseSymbol { validChars += p.GetSymbols() } return validChars } func (p *Passage) GetValidCharSets() []string { var validChars []string if p.valids&UseLower == UseLower { validChars = append(validChars, p.GetLowers()) } if p.valids&UseUpper == UseUpper { validChars = append(validChars, p.GetUppers()) } if p.valids&UseNumber == UseNumber { validChars = append(validChars, p.GetNumbers()) } if p.valids&UseSymbol == UseSymbol { validChars = append(validChars, p.GetSymbols()) } return validChars } func (p *Passage) SetPin(pin string) { p.pin = pin } func (p *Passage) GetPassword(door string) string { ret := "" hashing := p.pin + " - " + door shaArr := sha256.Sum256([]byte(hashing)) var sha []byte for i := range shaArr { sha = append(sha, shaArr[i]) } if p.requireEachCharSet { validChars := p.GetValidCharSets() for i := 0; i < p.length; i++ { set := i % len(validChars) ret += string(validChars[set][int(sha[i])%len(validChars)]) } } else { validChars := p.GetValidChars() for i := 0; i < p.length; i++ { ret += string(validChars[int(sha[i])%len(validChars)]) } } return ret } func (p *Passage) GetChecksum() int { ret := 0 sha := sha256.Sum256([]byte(p.pin)) for i := range sha { ret += int(sha[i]) } return ret } func (p *Passage) GetChecksumAsString() string { return strconv.Itoa(p.GetChecksum()) }