Last active
October 2, 2020 15:10
-
-
Save canassa/5b9ab0ab9013afac31065d41d912b514 to your computer and use it in GitHub Desktop.
Python CNPJ validation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
from typing import Union | |
class InvalidCNPJ(Exception): | |
pass | |
def clean_cnpj(value: Union[int, str]) -> str: | |
""" | |
Validates and cleans CNPJs, works with both string and ints as inputs | |
>>> clean_cnpj("57.823.152/0001-01") | |
'57.823.152/0001-01' | |
>>> clean_cnpj("32820286000148") | |
'32.820.286/0001-48' | |
>>> clean_cnpj("04520130000106") | |
'04.520.130/0001-06' | |
>>> clean_cnpj(4520130000106) | |
'04.520.130/0001-06' | |
>>> clean_cnpj("32.820.286/0000-67") | |
Traceback (most recent call last) | |
InvalidCNPJ: | |
""" | |
if isinstance(value, int): | |
v = f"{value:014d}" | |
elif isinstance(value, str): | |
v = re.sub(r"\D", "", value) | |
else: | |
raise InvalidCNPJ | |
if len(v) != 14: | |
raise InvalidCNPJ | |
# Suffixes start at 0001 | |
suffix = int(v[8:12]) | |
if suffix == 0: | |
raise InvalidCNPJ | |
# CNPJs with the following basic numbers are not valid: | |
# 11.111.111, 22.222.222, 33.333.333, 44.444.444, 55.555.555 | |
# 66.666.666, 77.777.777, 88.888.888, 99.999.999. | |
if v[0:8] in { | |
"11111111", | |
"22222222", | |
"33333333", | |
"44444444", | |
"55555555", | |
"66666666", | |
"77777777", | |
"88888888", | |
"99999999", | |
}: | |
raise InvalidCNPJ | |
d = [int(i) for i in v[:14]] | |
v1 = 5 * d[0] + 4 * d[1] + 3 * d[2] + 2 * d[3] | |
v1 += 9 * d[4] + 8 * d[5] + 7 * d[6] + 6 * d[7] | |
v1 += 5 * d[8] + 4 * d[9] + 3 * d[10] + 2 * d[11] | |
v1 = 11 - v1 % 11 | |
if v1 >= 10: | |
v1 = 0 | |
if v1 != d[12]: | |
raise InvalidCNPJ | |
v2 = 6 * d[0] + 5 * d[1] + 4 * d[2] + 3 * d[3] | |
v2 += 2 * d[4] + 9 * d[5] + 8 * d[6] + 7 * d[7] | |
v2 += 6 * d[8] + 5 * d[9] + 4 * d[10] + 3 * d[11] | |
v2 += 2 * d[12] | |
v2 = 11 - v2 % 11 | |
if v2 >= 10: | |
v2 = 0 | |
if v2 != d[13]: | |
raise InvalidCNPJ | |
# CNPJ with an suffix number greater than 0300 and with the first three positions | |
# of the BASIC number with 000 (zeros) will not be considered valid. | |
# Unless the basic number of the CNPJ is equal to 00.000.000, then it's valid. | |
if v[0:8] != "00000000" and v[0:3] == "000" and suffix > 300: | |
raise InvalidCNPJ | |
return f"{v[0:2]}.{v[2:5]}.{v[5:8]}/{v[8:12]}-{v[12:14]}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment