From e5e3836f20fd8d5d27ce514768bf6b86736bcdeb Mon Sep 17 00:00:00 2001 From: Semen Shaplygin Date: Sun, 7 Jan 2024 20:29:54 +0100 Subject: [PATCH 1/4] Update BENCHMARKS.md --- BENCHMARKS.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/BENCHMARKS.md b/BENCHMARKS.md index 396e6b9..1d1b523 100644 --- a/BENCHMARKS.md +++ b/BENCHMARKS.md @@ -2,6 +2,7 @@ ## BIK +``` goos: darwin goarch: arm64 pkg: github.com/sshaplygin/docs-code/bik @@ -9,9 +10,11 @@ BenchmarkValidateCorrect-10 8064954 140.7 ns/op 256 B/op BenchmarkGenerate-10 615589 1972 ns/op 240 B/op 18 allocs/op PASS ok github.com/sshaplygin/docs-code/bik 2.635s +``` ## INN +``` goos: darwin goarch: arm64 pkg: github.com/sshaplygin/docs-code/inn @@ -22,9 +25,11 @@ BenchmarkGenerateLegal-10 354616 3213 ns/op 801 B/op BenchmarkGeneratePhysical-10 492985 2419 ns/op 974 B/op 41 allocs/op PASS ok github.com/sshaplygin/docs-code/inn 7.215s +``` ## KPP +``` goos: darwin goarch: arm64 pkg: github.com/sshaplygin/docs-code/kpp @@ -32,9 +37,11 @@ BenchmarkValidateCorrect-10 5280958 218.9 ns/op 216 B/op BenchmarkGenerate-10 484114 2434 ns/op 385 B/op 22 allocs/op PASS ok github.com/sshaplygin/docs-code/kpp 2.810s +``` ## OGRN +``` goos: darwin goarch: arm64 pkg: github.com/sshaplygin/docs-code/ogrn @@ -42,9 +49,11 @@ BenchmarkValidateCorrect-10 2583738 457.3 ns/op 728 B/op BenchmarkGenerate-10 294908 3938 ns/op 841 B/op 45 allocs/op PASS ok github.com/sshaplygin/docs-code/ogrn 3.074s +``` ## OGRNIP +``` goos: darwin goarch: arm64 pkg: github.com/sshaplygin/docs-code/ogrnip @@ -52,3 +61,4 @@ BenchmarkValidateCorrect-10 1991065 580.4 ns/op 1008 B/op BenchmarkGenerate-10 403179 3100 ns/op 1010 B/op 46 allocs/op PASS ok github.com/sshaplygin/docs-code/ogrnip 3.411s +``` From 5937622ca28939c99d3ecfe5e2911d332938b15f Mon Sep 17 00:00:00 2001 From: Semen Shaplygin Date: Sun, 7 Jan 2024 20:30:43 +0100 Subject: [PATCH 2/4] Update README.md --- README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index d85475c..21c295f 100644 --- a/README.md +++ b/README.md @@ -12,12 +12,6 @@ It is not production ready public API! It is API could be change it the future. Status of implementation by code package: -- [ ] OGRN - - [ ] Generate method - - [x] Validate method -- [ ] OGRNIP - - [ ] Generate method - - [x] Validate method - [ ] OKATO - [ ] Generate method - [ ] Validate method @@ -25,7 +19,7 @@ Status of implementation by code package: - [ ] Generate method - [x] Validate method -Full supported codes: BIK, INN, KPP +Full supported codes: BIK, INN, KPP, OGRN, OGRNIP ## Usage From 7c53bf5656b4cd0b721417d401d7317c4bbc912c Mon Sep 17 00:00:00 2001 From: Saimon Shaplygin Date: Sun, 7 Jan 2024 21:47:29 +0100 Subject: [PATCH 3/4] add: snils --- BENCHMARKS.md | 20 ++++++++++ README.md | 5 +-- generate.go | 3 ++ snils/models.go | 91 +++++++++++++++++++++++++++++++++++++++++++++ snils/snils.go | 35 +++-------------- snils/snils_test.go | 21 +++++++++-- types.go | 1 + utils/helpers.go | 2 +- validate.go | 3 ++ 9 files changed, 142 insertions(+), 39 deletions(-) diff --git a/BENCHMARKS.md b/BENCHMARKS.md index 1d1b523..8354b6f 100644 --- a/BENCHMARKS.md +++ b/BENCHMARKS.md @@ -1,5 +1,13 @@ # Benchmarks +## Notice + +Command to update result: + +```bash +go test -benchmem -run=^$ -bench . github.com/sshaplygin/docs-code/snils >> BENCHMARKS.md +``` + ## BIK ``` @@ -62,3 +70,15 @@ BenchmarkGenerate-10 403179 3100 ns/op 1010 B/op 46 PASS ok github.com/sshaplygin/docs-code/ogrnip 3.411s ``` + +## SNILS + +``` +goos: darwin +goarch: arm64 +pkg: github.com/sshaplygin/docs-code/snils +BenchmarkValidateCorrect-10 4451258 263.2 ns/op 336 B/op 5 allocs/op +BenchmarkGenerate-10 1302042 895.3 ns/op 568 B/op 25 allocs/op +PASS +ok github.com/sshaplygin/docs-code/snils 3.768s +``` diff --git a/README.md b/README.md index 21c295f..52a2721 100644 --- a/README.md +++ b/README.md @@ -15,11 +15,8 @@ Status of implementation by code package: - [ ] OKATO - [ ] Generate method - [ ] Validate method -- [ ] SNILS - - [ ] Generate method - - [x] Validate method -Full supported codes: BIK, INN, KPP, OGRN, OGRNIP +Full supported codes: BIK, INN, KPP, OGRN, OGRNIP, SNILS ## Usage diff --git a/generate.go b/generate.go index e5f6345..2d7b16e 100644 --- a/generate.go +++ b/generate.go @@ -6,6 +6,7 @@ import ( "github.com/sshaplygin/docs-code/kpp" "github.com/sshaplygin/docs-code/ogrn" "github.com/sshaplygin/docs-code/ogrnip" + "github.com/sshaplygin/docs-code/snils" ) type GenerateFunc func() string @@ -23,6 +24,8 @@ func Generate(docType DocType) string { callFunc = ogrn.Generate case OGRNIP: callFunc = ogrnip.Generate + case SNILS: + callFunc = snils.Generate } if callFunc == nil { diff --git a/snils/models.go b/snils/models.go index a7c2471..06918ce 100644 --- a/snils/models.go +++ b/snils/models.go @@ -1,3 +1,94 @@ package snils +import ( + "fmt" + "strconv" + "strings" + + "github.com/sshaplygin/docs-code/models" + "github.com/sshaplygin/docs-code/utils" +) + const packageName = "snils" + +type Numbers []int + +const checkSumLength = 2 + +type checkSum int + +type SNILSStruct struct { + numbers Numbers + checkSum checkSum +} + +func (ss *SNILSStruct) String() string { + var res strings.Builder + res.Grow(snilsFullLength) + + for i := 0; i < len(ss.numbers); i++ { + if i%3 == 0 && i != 0 { + res.WriteString("-") + } + res.WriteString(strconv.Itoa(ss.numbers[i])) + } + + res.WriteString(" ") + res.WriteString(utils.StrCode(int(ss.checkSum), checkSumLength)) + + return res.String() +} + +func (ss *SNILSStruct) IsValid() (bool, error) { + return ss.calculateCheckSum() == ss.checkSum, nil +} + +const ( + snilsFullLength = 14 + snilsShrinkLength = 11 +) + +func ParseSNILS(snils string) (*SNILSStruct, error) { + if len(snils) != snilsFullLength { + return nil, &models.CommonError{ + Method: packageName, + Err: models.ErrInvalidLength, + } + } + + fSnils := strings.ReplaceAll(snils, "-", "") + fSnils = strings.ReplaceAll(fSnils, " ", "") + + if len(fSnils) != snilsShrinkLength { + return nil, ErrInvalidFormattedLength + } + + snilsArr, err := utils.StrToArr(fSnils) + if err != nil { + return nil, fmt.Errorf("parse raw %s: %w", packageName, err) + } + + return &SNILSStruct{ + numbers: Numbers(snilsArr[:len(snilsArr)-2]), + checkSum: checkSum(utils.SliceToInt(snilsArr[len(snilsArr)-2:])), + }, nil +} + +func NewSNILS() *SNILSStruct { + data := &SNILSStruct{ + numbers: Numbers(utils.CodeToInts(int(utils.RandomDigits(9)))), + } + + data.checkSum = data.calculateCheckSum() + + return data +} + +func (ss *SNILSStruct) calculateCheckSum() checkSum { + var hashSum int + for i, v := range ss.numbers { + hashSum += v * (len(ss.numbers) - i) + } + + return checkSum(hashSum % 101 % 100) +} diff --git a/snils/snils.go b/snils/snils.go index 82b9d5c..09f7f1f 100644 --- a/snils/snils.go +++ b/snils/snils.go @@ -1,46 +1,21 @@ package snils import ( - "strconv" - "strings" - - "github.com/sshaplygin/docs-code/models" - "github.com/sshaplygin/docs-code/utils" + "fmt" ) // Validate check to valid SNILS format // example: input format is 112-233-445 95 func Validate(snils string) (bool, error) { - if len(snils) != 14 { - return false, &models.CommonError{ - Method: packageName, - Err: models.ErrInvalidLength, - } - } - - fSnils := strings.ReplaceAll(snils, "-", "") - fSnils = strings.ReplaceAll(fSnils, " ", "") - - if len(fSnils) != 11 { - return false, ErrInvalidFormattedLength - } - - snilsArr, err := utils.StrToArr(fSnils) + snilsData, err := ParseSNILS(snils) if err != nil { - return false, err - } - - hashSum := 0 - hashLen := len(fSnils) - 2 - code, _ := strconv.Atoi(fSnils[hashLen:]) - for i, v := range snilsArr[:hashLen] { - hashSum += v * (hashLen - i) + return false, fmt.Errorf("parse %s model: %w", packageName, err) } - return hashSum%101 == code, nil + return snilsData.IsValid() } // Generate generate random func Generate() string { - panic("not implemented!") + return NewSNILS().String() } diff --git a/snils/snils_test.go b/snils/snils_test.go index 9666213..de5e78b 100644 --- a/snils/snils_test.go +++ b/snils/snils_test.go @@ -75,7 +75,6 @@ func TestValidate(t *testing.T) { }, { Code: "112-233-445 98", - Error: nil, IsValid: false, }, { @@ -85,7 +84,6 @@ func TestValidate(t *testing.T) { }, { Code: "112-233-445 95", - Error: nil, IsValid: true, }, { @@ -109,7 +107,22 @@ func TestValidate(t *testing.T) { } func Test_Generate(t *testing.T) { - require.Panics(t, func() { + for i := 0; i < 10; i++ { + snils := Generate() + isValid, err := Validate(snils) + require.NoError(t, err, fmt.Sprintf("invalid ogrnip value: %s", snils)) + + assert.True(t, isValid) + } +} + +func BenchmarkValidateCorrect(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = Validate("112-233-445 95") + } +} +func BenchmarkGenerate(b *testing.B) { + for i := 0; i < b.N; i++ { Generate() - }) + } } diff --git a/types.go b/types.go index 4075b3f..db22b59 100644 --- a/types.go +++ b/types.go @@ -8,4 +8,5 @@ const ( KPP OGRN OGRNIP + SNILS ) diff --git a/utils/helpers.go b/utils/helpers.go index cef0a99..56f4037 100644 --- a/utils/helpers.go +++ b/utils/helpers.go @@ -81,7 +81,7 @@ func StrCode(val, length int) string { n := length if len(code) > length { - panic(fmt.Sprintf("invalid int code length: %d, %d", len(code), length)) + panic(fmt.Sprintf("invalid int code '%s' length: %d, %d", code, len(code), length)) } str.Grow(n) diff --git a/validate.go b/validate.go index ccde492..bc4c1ce 100644 --- a/validate.go +++ b/validate.go @@ -6,6 +6,7 @@ import ( "github.com/sshaplygin/docs-code/kpp" "github.com/sshaplygin/docs-code/ogrn" "github.com/sshaplygin/docs-code/ogrnip" + "github.com/sshaplygin/docs-code/snils" ) type ValidateFunc func(code string) (bool, error) @@ -23,6 +24,8 @@ func Validate(docType DocType, code string) (bool, error) { callFunc = ogrn.Validate case OGRNIP: callFunc = ogrnip.Validate + case SNILS: + callFunc = snils.Validate } if callFunc == nil { From e37151cc8b0b33d52123115924236168601f6483 Mon Sep 17 00:00:00 2001 From: Saimon Shaplygin Date: Sun, 7 Jan 2024 22:07:05 +0100 Subject: [PATCH 4/4] fix --- fts/fts.go | 2 +- fts/tax_departs.go | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/fts/fts.go b/fts/fts.go index 6843060..0761c18 100644 --- a/fts/fts.go +++ b/fts/fts.go @@ -150,7 +150,7 @@ func (csc ConstitutionRegionCode) Ints() []int { } func GenerateConstitutionSubjectCode() ConstitutionRegionCode { - return regionsCodes[utils.Random(0, len(regionsCodes)-1)] + return supportedRegionsCodes[utils.Random(0, len(supportedRegionsCodes)-1)] } type RegionTaxServiceNumber int diff --git a/fts/tax_departs.go b/fts/tax_departs.go index 9caefb0..c9dfae3 100644 --- a/fts/tax_departs.go +++ b/fts/tax_departs.go @@ -5,6 +5,8 @@ type TaxDepart struct { Branches map[RegionTaxServiceNumber]string } +var supportedRegionsCodes []ConstitutionRegionCode + var SupportedTaxDepartments = map[ConstitutionRegionCode]TaxDepart{ 0: { Name: `Федеральная налоговая служба`, @@ -1556,8 +1558,7 @@ var SupportedTaxDepartments = map[ConstitutionRegionCode]TaxDepart{ }, }, 84: { - Name: `Межрайонная инспекция Федеральной налоговой службы №2 по Красноярскому краю, Таймырскому (Долгано-Ненецкому) и Эвенкийскому автономным округам`, - Branches: map[RegionTaxServiceNumber]string{}, + Name: `Межрайонная инспекция Федеральной налоговой службы №2 по Красноярскому краю, Таймырскому (Долгано-Ненецкому) и Эвенкийскому автономным округам`, }, 86: { Name: `Управление Федеральной налоговой службы по Ханты-Мансийскому автономному округу - Югре`, @@ -1588,8 +1589,7 @@ var SupportedTaxDepartments = map[ConstitutionRegionCode]TaxDepart{ }, }, 88: { - Name: `Межрайонная инспекция Федеральной налоговой службы №3 по Красноярскому краю, Таймырскому (Долгано-Ненецкому) и Эвенкийскому автономным округам`, - Branches: map[RegionTaxServiceNumber]string{}, + Name: `Межрайонная инспекция Федеральной налоговой службы №3 по Красноярскому краю, Таймырскому (Долгано-Ненецкому) и Эвенкийскому автономным округам`, }, 89: { Name: `Управление Федеральной налоговой службы по Ямало-Ненецкому автономному округу`, @@ -1628,3 +1628,10 @@ var SupportedTaxDepartments = map[ConstitutionRegionCode]TaxDepart{ }, }, } + +func init() { + supportedRegionsCodes = make([]ConstitutionRegionCode, 0, len(SupportedTaxDepartments)) + for region := range SupportedTaxDepartments { + supportedRegionsCodes = append(supportedRegionsCodes, region) + } +}