package inns // The package implements the basic // Russian Federation INN format // storing it in int64 to keep // searching and storing as // quick as possible. import ( "strings" "unicode" "strconv" "fmt" "slices" ) type InnType uint8 const ( IncorrectInnType InnType = iota LegalInnType IndividualInnType ) func removeSpaces(s string) string { return strings.Map(func(r rune) rune{ if unicode.IsSpace(r) { return -1 } return r }, s) } type Inn int64 func NewFromInt64(innRaw int64) (Inn, error) { inn := Inn(innRaw) if !inn.isCorrectLen() { return -1, IncorrectLenErr } if !inn.isSumCorrect() { return -1, SumsNotMatchErr } return inn, nil } // Convert string with spaces into the INN // and return error if anything is wrong with it. func NewFromStr(str string) (Inn, error) { str = removeSpaces(str) innRaw, err := strconv.ParseInt(str, 10, 64) if err != nil { return -1, IncorrectFormatErr } return NewFromInt64(innRaw) } func (inn Inn) Type() InnType { ln := inn.length() switch ln { case 9, 10: return LegalInnType case 11, 12: return IndividualInnType } return IncorrectInnType } func (inn Inn) length() int { ln := 0 for { if inn == 0 { break } inn /= 10 ln++ } if ln == 9 || ln == 11 { ln++ } return ln } func (inn Inn) isCorrectLen() bool { ln := inn.length() if ln == 9 || ln == 11 { ln++ } return ln == 10 || ln == 12 } var ( // Koefs for the control sum. innSum10 = [9]int64{ 2, 4, 10, 3, 5, 9, 4, 6, 8, } innSum11 = [10]int64{ 7, 2, 4, 10, 3, 5, 9, 4, 6, 8, } innSum12 = [11]int64{ 3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8, } ) // Get the integer representation of digits in string INN. func (inn Inn) digits() []int64 { ln := inn.length() v := int64(inn) ret := make([]int64, ln) for i := 0 ; i" }