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:]) }