88 lines
1.4 KiB
Go
88 lines
1.4 KiB
Go
package cnpj
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
cnpjP1 = []int{5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2}
|
|
cnpjP2 = []int{6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2}
|
|
)
|
|
|
|
const alphaChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
|
|
func Generate() string {
|
|
return generate(false)
|
|
}
|
|
|
|
func GenerateAlpha() string {
|
|
return generate(true)
|
|
}
|
|
|
|
func generate(alpha bool) string {
|
|
for {
|
|
var b strings.Builder
|
|
b.Grow(14)
|
|
for range 12 {
|
|
if alpha {
|
|
b.WriteByte(alphaChars[rand.Intn(len(alphaChars))])
|
|
} else {
|
|
b.WriteByte(byte('0' + rand.Intn(10)))
|
|
}
|
|
}
|
|
s := b.String()
|
|
if isRepetitive(s) {
|
|
continue
|
|
}
|
|
dv1 := computeDV(s, cnpjP1, alpha)
|
|
s2 := s + string(byte('0'+dv1))
|
|
dv2 := computeDV(s2, cnpjP2, alpha)
|
|
return s + string(byte('0'+dv1)) + string(byte('0'+dv2))
|
|
}
|
|
}
|
|
|
|
func computeDV(s string, table []int, alpha bool) int {
|
|
total := 0
|
|
for i, w := range table {
|
|
c := s[i]
|
|
var val int
|
|
if alpha {
|
|
val = alphaValue(rune(c))
|
|
} else {
|
|
val = int(c - '0')
|
|
}
|
|
total += val * w
|
|
}
|
|
r := total % 11
|
|
if r >= 2 {
|
|
return 11 - r
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func alphaValue(r rune) int {
|
|
return int(r) - 48
|
|
}
|
|
|
|
func isRepetitive(s string) bool {
|
|
if len(s) == 0 {
|
|
return false
|
|
}
|
|
c := s[0]
|
|
for i := 1; i < len(s); i++ {
|
|
if s[i] != c {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func Format(cnpj string) string {
|
|
if len(cnpj) != 14 {
|
|
return cnpj
|
|
}
|
|
return fmt.Sprintf("%s.%s.%s/%s-%s",
|
|
cnpj[:2], cnpj[2:5], cnpj[5:8], cnpj[8:12], cnpj[12:])
|
|
}
|