br-cpf-cnpj 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,12 @@
1
+ from .__version__ import __version__, __author__
2
+ from .validator import is_valid_cpf, is_valid_cnpj
3
+ from .generator import generate_random_cnpj, generate_random_cpf
4
+
5
+ __all__ = [
6
+ '__version__',
7
+ '__author__',
8
+ 'is_valid_cpf',
9
+ 'is_valid_cnpj',
10
+ 'generate_random_cpf',
11
+ 'generate_random_cnpj'
12
+ ]
@@ -0,0 +1,2 @@
1
+ __version__ = "0.1.1"
2
+ __author__ = "Renan Campista"
@@ -0,0 +1,63 @@
1
+ def calculate_dv_cpf(base: str) -> tuple[int, int]:
2
+ """Calculates the two verification digits (DVs) for a given CPF base.
3
+
4
+ Args:
5
+ base (str): The first 9 digits of the CPF number.
6
+ Returns:
7
+ tuple[int, int]: A tuple containing the two calculated verification digits.
8
+ """
9
+ if len(base) != 9 or not base.isdigit():
10
+ raise ValueError("CPF base must have exactly 9 digits")
11
+
12
+ weight = 10
13
+ total = 0
14
+ for digit in base:
15
+ total += int(digit) * weight
16
+ weight -= 1
17
+
18
+ resto = total % 11
19
+ dv1 = 0 if resto < 2 else 11 - resto
20
+
21
+ weight = 11
22
+ total = 0
23
+ for digit in base + str(dv1):
24
+ total += int(digit) * weight
25
+ weight -= 1
26
+
27
+ resto = total % 11
28
+ dv2 = 0 if resto < 2 else 11 - resto
29
+
30
+ return dv1, dv2
31
+
32
+
33
+ def calculate_dv_cnpj(base: str) -> tuple[int, int]:
34
+ """Calculates the two verification digits (DVs) for a given CNPJ base.
35
+
36
+ Args:
37
+ base (str): The first 12 characters of the CNPJ number.
38
+ Returns:
39
+ tuple[int, int]: A tuple containing the two calculated verification digits.
40
+ """
41
+ if len(base) != 12:
42
+ raise ValueError("CNPJ base must have exactly 12 characters")
43
+
44
+ weight = 2
45
+ total = 0
46
+ for i in range(11, -1, -1):
47
+ total += (ord(base[i]) - ord('0')) * weight
48
+ weight = weight + 1 if weight < 9 else 2
49
+
50
+ resto = total % 11
51
+ dv1 = 0 if resto < 2 else 11 - resto
52
+
53
+ weight = 2
54
+ total = 0
55
+ base_dv1 = base + str(dv1)
56
+ for i in range(12, -1, -1):
57
+ total += (ord(base_dv1[i]) - ord('0')) * weight
58
+ weight = weight + 1 if weight < 9 else 2
59
+
60
+ resto = total % 11
61
+ dv2 = 0 if resto < 2 else 11 - resto
62
+
63
+ return dv1, dv2
@@ -0,0 +1,50 @@
1
+ import random
2
+ import string
3
+
4
+ from .calculation import calculate_dv_cpf, calculate_dv_cnpj
5
+
6
+
7
+ def generate_random_cpf(masked: bool = False) -> str:
8
+ """
9
+ Generates a valid random CPF number (only digits).
10
+
11
+ Args:
12
+ masked (bool): If True, generates masked CPF (with dots and hyphen).
13
+ If False, generates numeric-only CPF.
14
+ Returns:
15
+ str: A valid CPF with 11 digits.
16
+ """
17
+ base = ''.join(str(random.randint(0, 9)) for _ in range(9))
18
+
19
+ dv1, dv2 = calculate_dv_cpf(base)
20
+
21
+ if masked:
22
+ return f"{base[:3]}.{base[3:6]}.{base[6:9]}-{dv1}{dv2}"
23
+ return f"{base}{dv1}{dv2}"
24
+
25
+
26
+ def generate_random_cnpj(masked: bool = False, alphanumeric: bool = True) -> str:
27
+ """
28
+ Generates a valid random CNPJ number.
29
+
30
+ Args:
31
+ masked (bool): If True, generates masked CNPJ (with dots, slashes, and hyphen).
32
+ If False, generates numeric-only CNPJ.
33
+ alphanumeric (bool): If True, generates alphanumeric CNPJ.
34
+ If False, generates numeric-only CNPJ.
35
+
36
+ Returns:
37
+ str: A valid CNPJ with 14 characters.
38
+ """
39
+ if alphanumeric:
40
+ charset = string.digits + string.ascii_uppercase
41
+ else:
42
+ charset = string.digits
43
+
44
+ base = ''.join(random.choice(charset) for _ in range(12))
45
+
46
+ dv1, dv2 = calculate_dv_cnpj(base)
47
+
48
+ if masked:
49
+ return f"{base[:2]}.{base[2:5]}.{base[5:8]}/{base[8:12]}-{dv1}{dv2}"
50
+ return f"{base}{dv1}{dv2}"
@@ -0,0 +1,15 @@
1
+ import re
2
+
3
+
4
+ def normalize_cpf(value: str | int) -> str:
5
+ """Normalizes a CPF number by removing any non-digit characters and leading zeros."""
6
+ if not value or not isinstance(value, (str, int)):
7
+ return ''
8
+ return re.sub(r'\D', '', str(value))
9
+
10
+
11
+ def normalize_cnpj(value: str) -> str:
12
+ """Normalizes a CNPJ by removing formatting characters and uppercasing letters."""
13
+ if not value or not isinstance(value, str):
14
+ return ''
15
+ return re.sub(r'[^A-Za-z0-9]', '', value).upper()
@@ -0,0 +1,41 @@
1
+ from .normalize import normalize_cnpj, normalize_cpf
2
+ from .calculation import calculate_dv_cnpj, calculate_dv_cpf
3
+
4
+
5
+ def is_valid_cnpj(value: str) -> bool:
6
+ """Checks if the given value is a valid CNPJ number.
7
+
8
+ Args:
9
+ value (str): CNPJ value (numeric or alphanumeric).
10
+ Returns:
11
+ bool: True if the CNPJ number is valid, False otherwise.
12
+ """
13
+ cnpj = normalize_cnpj(value)
14
+
15
+ if len(cnpj) != 14 or cnpj == cnpj[0] * 14:
16
+ return False
17
+
18
+ base = cnpj[:12]
19
+ dv1, dv2 = calculate_dv_cnpj(base)
20
+
21
+ return (dv1, dv2) == (int(cnpj[12]), int(cnpj[13]))
22
+
23
+
24
+ def is_valid_cpf(value: str | int) -> bool:
25
+ """Checks if the given value is a valid CPF number.
26
+
27
+ Args:
28
+ value (str | int): The CPF number to validate.
29
+ NOTE: If the value is a number, it will be converted to a string and any leading zeros will be removed.
30
+ Returns:
31
+ bool: True if the CPF number is valid, False otherwise.
32
+ """
33
+ cpf = normalize_cpf(value)
34
+
35
+ if len(cpf) != 11 or cpf == cpf[0] * 11:
36
+ return False
37
+
38
+ base = cpf[:9]
39
+ dv1, dv2 = calculate_dv_cpf(base)
40
+
41
+ return (dv1, dv2) == (int(cpf[9]), int(cpf[10]))
@@ -0,0 +1,220 @@
1
+ Metadata-Version: 2.4
2
+ Name: br-cpf-cnpj
3
+ Version: 0.1.1
4
+ Summary: CPF and CNPJ validation and generation with support for alphanumeric CNPJ
5
+ Author-email: RenanCampista <rennan.campistah@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/RenanCampista/br-cpf-cnpj
8
+ Project-URL: Repository, https://github.com/RenanCampista/br-cpf-cnpj
9
+ Project-URL: Issues, https://github.com/RenanCampista/br-cpf-cnpj/issues
10
+ Keywords: cpf,cnpj,brasil,validation,validação
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Provides-Extra: dev
19
+ Requires-Dist: pytest; extra == "dev"
20
+ Dynamic: license-file
21
+
22
+ # 📦 py-cpf-cnpj
23
+
24
+ A Python library for **CPF and CNPJ validation and generation**, with **support for the new alphanumeric CNPJ standard**.
25
+
26
+ ---
27
+
28
+ ## ✨ Features
29
+
30
+ - ✅ CPF validation
31
+ - ✅ CNPJ validation (numeric and alphanumeric)
32
+ - 🔢 Random CPF generator
33
+ - 🔡 Random CNPJ generator (numeric or alphanumeric)
34
+ - 🧪 Fully tested with pytest
35
+ ---
36
+
37
+ ## 📥 Installation
38
+
39
+ ```bash
40
+ pip install py-cpf-cnpj
41
+ ```
42
+
43
+ ---
44
+
45
+ ## 🚀 Usage
46
+ ### Validate CPF
47
+
48
+ ```python
49
+ from py_cpf_cnpj import is_valid_cpf
50
+
51
+ is_valid_cpf("529.982.247-25")
52
+ # True
53
+ ```
54
+
55
+ ### Validate CNPJ
56
+
57
+ ```python
58
+ from py_cpf_cnpj import is_valid_cnpj
59
+
60
+ # Validate numeric CNPJ
61
+ is_valid_cnpj("11.222.333/0001-81")
62
+ # True
63
+
64
+ # Validate alphanumeric CNPJ
65
+ is_valid_cnpj("2P.76B.MNX/0001-66")
66
+ # True
67
+ ```
68
+
69
+ ### Generate Random CPF
70
+
71
+ ```python
72
+ from py_cpf_cnpj import generate_random_cpf
73
+
74
+ cpf = generate_random_cpf(masked=True)
75
+ print(cpf)
76
+ # e.g., "123.456.789-09"
77
+
78
+ cpf_unmasked = generate_random_cpf(masked=False)
79
+ print(cpf_unmasked)
80
+ # e.g., "12345678909"
81
+ ```
82
+
83
+ ### Generate Random CNPJ
84
+
85
+ ```python
86
+ from py_cpf_cnpj import generate_random_cnpj
87
+
88
+ # Generate numeric CNPJ
89
+ cnpj_numeric = generate_random_cnpj(alphanumeric=False, masked=True)
90
+ print(cnpj_numeric)
91
+ # e.g., "12.345.678/0001-95"
92
+
93
+ # Generate alphanumeric CNPJ
94
+ cnpj_alphanumeric = generate_random_cnpj(alphanumeric=True, masked=False)
95
+ print(cnpj_alphanumeric)
96
+ # e.g., "RSASKDDW000100"
97
+ ```
98
+
99
+ ---
100
+
101
+ ## 🧠 How it works
102
+ ### CPF
103
+ - Uses fixed weights (10 → 2, then 11 → 2)
104
+ - Applies the official modulo 11 algorithm
105
+ - Prevents invalid repeated-digit CPFs (e.g. `11111111111`)
106
+
107
+ ### CNPJ (Alphanumeric)
108
+ - Supports digits (0–9) and uppercase letters (A–Z)
109
+ - Characters are converted using:
110
+ `value = ord(char) - ord('0')`
111
+ - Weights cycle from 2 → 9
112
+
113
+ ---
114
+
115
+ ## Contributing
116
+ Contributions are very welcome!
117
+ Feel free to open issues, suggest improvements, or submit pull requests.
118
+
119
+
120
+ ## 📄 License
121
+ MIT License.
122
+
123
+ ---
124
+
125
+ # Versão em Português
126
+ # 📦 py-cpf-cnpj
127
+ Uma biblioteca Python para **validação e geração de CPF e CNPJ**, com **suporte ao novo padrão de CNPJ alfanumérico**.
128
+
129
+ ---
130
+
131
+ ## ✨ Funcionalidades
132
+
133
+ - ✅ Validação de CPF
134
+ - ✅ Validação de CNPJ (numérico e alfanumérico)
135
+ - 🔢 Gerador de CPF aleatório
136
+ - 🔡 Gerador de CNPJ aleatório (numérico ou alfanumérico)
137
+ - 🧪 Testes automatizados com pytest
138
+
139
+ ---
140
+
141
+ ## 📥 Instalação
142
+
143
+ ```bash
144
+ pip install py-cpf-cnpj
145
+ ```
146
+
147
+ ## 🚀 Uso
148
+ ### Validar CPF
149
+
150
+ ```python
151
+ from py_cpf_cnpj import is_valid_cpf
152
+
153
+ is_valid_cpf("529.982.247-25")
154
+ # True
155
+ ```
156
+
157
+ ### Validar CNPJ
158
+
159
+ ```python
160
+ from py_cpf_cnpj import is_valid_cnpj
161
+
162
+ # Validar CNPJ numérico
163
+ is_valid_cnpj("11.222.333/0001-81")
164
+ # True
165
+
166
+ # Validar CNPJ alfanumérico
167
+ is_valid_cnpj("2P.76B.MNX/0001-66")
168
+ # True
169
+ ```
170
+
171
+ ### Gerar CPF Aleatório
172
+
173
+ ```python
174
+ from py_cpf_cnpj import generate_random_cpf
175
+
176
+ cpf = generate_random_cpf(masked=True)
177
+ print(cpf)
178
+ # e.g., "123.456.789-09"
179
+
180
+ cpf_unmasked = generate_random_cpf(masked=False)
181
+ print(cpf_unmasked)
182
+ # e.g., "12345678909"
183
+ ```
184
+
185
+ ### Gerar CNPJ Aleatório
186
+
187
+ ```python
188
+ from py_cpf_cnpj import generate_random_cnpj
189
+
190
+ # Gerar CNPJ numérico
191
+ cnpj_numeric = generate_random_cnpj(alphanumeric=False, masked=True)
192
+ print(cnpj_numeric)
193
+ # e.g., "12.345.678/0001-95"
194
+
195
+ # Gerar CNPJ alfanumérico
196
+ cnpj_alphanumeric = generate_random_cnpj(alphanumeric=True, masked=False)
197
+ print(cnpj_alphanumeric)
198
+ # e.g., "RSASKDDW000100"
199
+ ```
200
+
201
+ ---
202
+
203
+ ## 🧠 Como Funciona
204
+ ### CPF
205
+ - Pesos fixos (10 → 2 e 11 → 2)
206
+ - Algoritmo módulo 11
207
+ - Rejeita CPFs inválidos com dígitos repetidos (e.g. `11111111111`)
208
+
209
+ ### CNPJ (Alfanumérico)
210
+ - Aceita números (0–9) e letras (A–Z)
211
+ - Conversão baseada em valor ASCII:
212
+ `value = ord(char) - ord('0')`
213
+ - Pesos cíclicos de 2 → 9
214
+
215
+ ## Contribuindo
216
+ Contribuições são muito bem-vindas!
217
+ Sinta-se à vontade para abrir issues, sugerir melhorias ou enviar pull requests.
218
+
219
+ ## 📄 License
220
+ MIT License.
@@ -0,0 +1,11 @@
1
+ br_cpf_cnpj/__init__.py,sha256=y7oEnZfCZrcQ3i3q6D5DKUtnaiAJyrV5NMcGHp5pWE0,322
2
+ br_cpf_cnpj/__version__.py,sha256=_jkbh1MX9fo13gQTcQ0xuZh1RTrPX7gOAHFPeY4NNUA,52
3
+ br_cpf_cnpj/calculation.py,sha256=Us5FymKDzHB43pO2bDie6d1k2dVYxjx9kE98lxa042k,1776
4
+ br_cpf_cnpj/generator.py,sha256=UmoCZht1ucXk-CO4UPOCVeL7FhcqHcGW5F5enpGBMaE,1529
5
+ br_cpf_cnpj/normalize.py,sha256=fnzd2TkEp4xno-mHgMIEaA5hRqPH8RmaxjEwgQMBZZw,523
6
+ br_cpf_cnpj/validator.py,sha256=A_Cc2wLHMvLKISlrahBYyoD0S8gLANs75PUTM-MNo4o,1217
7
+ br_cpf_cnpj-0.1.1.dist-info/licenses/LICENSE,sha256=IArap4WCSn0OBMYbrjTFvPLT36uj-2yfo5FsbPcwAzc,1092
8
+ br_cpf_cnpj-0.1.1.dist-info/METADATA,sha256=7nRGwkyeSss6RdxAcL-Xt-yb5TCbJkhSt9BeeYjxW0A,4705
9
+ br_cpf_cnpj-0.1.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
10
+ br_cpf_cnpj-0.1.1.dist-info/top_level.txt,sha256=V6jFhRasLPhiHAWntnuoCud6u0FuJ0RPT_vZg2AAQb0,12
11
+ br_cpf_cnpj-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Renan Campista
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ br_cpf_cnpj