Init.
This commit is contained in:
commit
c54d17ee30
5 changed files with 294 additions and 0 deletions
3
go.mod
Normal file
3
go.mod
Normal file
|
@ -0,0 +1,3 @@
|
|||
module vultras.su/core/biz
|
||||
|
||||
go 1.21.8
|
11
inns/errors.go
Normal file
11
inns/errors.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package inns
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
IncorrectFormatErr = errors.New("incorrect INN format")
|
||||
IncorrectLenErr = errors.New("incorrect INN length")
|
||||
SumsNotMatchErr = errors.New("control sums do not match")
|
||||
)
|
80
inns/inns_test.go
Normal file
80
inns/inns_test.go
Normal file
|
@ -0,0 +1,80 @@
|
|||
package inns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var (
|
||||
testStrInns = []string{
|
||||
"663802 397223",
|
||||
"8252 47222169",
|
||||
"8712530 92145",
|
||||
"0873 820 72512",
|
||||
"227 62 3382327",
|
||||
"886 62 2222010",
|
||||
"464 350 209157",
|
||||
"758956582077",
|
||||
"212551260755",
|
||||
"0432444 61455",
|
||||
"428880301819",
|
||||
"61309 59 33498",
|
||||
"667344101205",
|
||||
"6189115998",
|
||||
"426 1455105",
|
||||
"562 5340715",
|
||||
"6588135629",
|
||||
"253 7102466",
|
||||
"8195196 357",
|
||||
"23838 17246",
|
||||
"812 5976843",
|
||||
"4710 107563",
|
||||
"3732 71726",
|
||||
"2170 439945",
|
||||
"2193865 820",
|
||||
"8122 281402",
|
||||
}
|
||||
testStrInnsErr = []string{
|
||||
"66380a2397223",
|
||||
"825247222eu169",
|
||||
"8712530921457553",
|
||||
"087753382072512",
|
||||
"22762hetu3382327",
|
||||
"886ao622222010",
|
||||
"4643he50209157",
|
||||
"75895 te 6582077",
|
||||
"2asn12551260755",
|
||||
"043abc244461455",
|
||||
"428880err301819",
|
||||
"0x613095933498",
|
||||
"667344101205h",
|
||||
"618911xerr5998",
|
||||
"426x1455105",
|
||||
"562x5340715",
|
||||
"658813moreerr5629",
|
||||
"253x7102466",
|
||||
"8195196x357",
|
||||
"23check838 17246",
|
||||
"8check12x5976843",
|
||||
"4710x107563",
|
||||
"03732x71726",
|
||||
"2170x439945",
|
||||
"2193865x820",
|
||||
"81shit2 281402",
|
||||
}
|
||||
)
|
||||
|
||||
func TestInnFromStr(t *testing.T) {
|
||||
for _, rawInn := range testStrInns {
|
||||
_, err := NewFromStr(rawInn)
|
||||
if err != nil {
|
||||
t.Fatalf("InnFromStr(%q), err == %q", rawInn, err)
|
||||
}
|
||||
}
|
||||
for _, rawInn := range testStrInnsErr {
|
||||
_, err := NewFromStr(rawInn)
|
||||
if err == nil {
|
||||
t.Fatalf("InnFromStr(%q), err == %v, must be though", rawInn, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
193
inns/main.go
Normal file
193
inns/main.go
Normal file
|
@ -0,0 +1,193 @@
|
|||
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<ln ; i++{
|
||||
ret[i] = v % 10
|
||||
v /= 10
|
||||
}
|
||||
slices.Reverse(ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
//
|
||||
func (inn Inn) specifiedSum() int64 {
|
||||
ln := inn.length()
|
||||
v := int64(inn)
|
||||
switch ln {
|
||||
case 10:
|
||||
return v%10
|
||||
case 12:
|
||||
return v%100
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the supposed control sum rune. (the last number)
|
||||
func (inn Inn) sum() int64 {
|
||||
d := inn.digits()
|
||||
ln := inn.length()
|
||||
switch ln {
|
||||
case 10 :
|
||||
var n10 int64
|
||||
for i, ni := range d[:9] {
|
||||
n10 += innSum10[i] * ni
|
||||
}
|
||||
n10 = (n10 % 11) % 10
|
||||
return n10
|
||||
case 12 :
|
||||
var n11 int64
|
||||
for i, ni := range d[:10] {
|
||||
n11 += innSum11[i] * ni
|
||||
}
|
||||
n11 = (n11 % 11) % 10
|
||||
|
||||
var n12 int64
|
||||
for i, ni := range d[:10] {
|
||||
n12 += innSum12[i] * ni
|
||||
}
|
||||
n12 += innSum12[10] * n11
|
||||
n12 = (n12 % 11) % 10
|
||||
|
||||
return n11*10 + n12
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (inn Inn) isSumCorrect() bool {
|
||||
return inn.specifiedSum() == inn.sum()
|
||||
}
|
||||
|
||||
func (inn Inn) String() string {
|
||||
return fmt.Sprintf("%d", inn)
|
||||
}
|
||||
|
||||
// Fancy way to print INN with space delimiters.
|
||||
func (inn Inn) Fancy() string {
|
||||
ln := inn.length()
|
||||
str := fmt.Sprintf("%d", inn)
|
||||
|
||||
// Adding zero depending on length.
|
||||
if len(str) == 9 || len(str) == 11 {
|
||||
str = "0"+str
|
||||
}
|
||||
|
||||
switch ln {
|
||||
case 10 :
|
||||
return fmt.Sprintf("%s %s %s", str[:4], str[4:9], str[9:])
|
||||
case 12 :
|
||||
return fmt.Sprintf("%s %s %s", str[:4], str[4:10], str[10:])
|
||||
}
|
||||
|
||||
// Reaching the point if the length is incorrect.
|
||||
return "<"+IncorrectLenErr.Error()+">"
|
||||
}
|
||||
|
7
main.go
Normal file
7
main.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package main
|
||||
|
||||
// The package contains
|
||||
// business related types and functions
|
||||
// that are used across related applications
|
||||
// and packages.
|
||||
|
Loading…
Reference in a new issue