From 6d7ba58f880be618ade07f8ea080fe8c4bf8a896 Mon Sep 17 00:00:00 2001 From: cyfraeviolae Date: Wed, 3 Apr 2024 03:10:44 -0400 Subject: venv --- .../faker/providers/ssn/es_MX/__init__.py | 261 +++++++++++++++++++++ .../ssn/es_MX/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 10138 bytes 2 files changed, 261 insertions(+) create mode 100644 venv/lib/python3.11/site-packages/faker/providers/ssn/es_MX/__init__.py create mode 100644 venv/lib/python3.11/site-packages/faker/providers/ssn/es_MX/__pycache__/__init__.cpython-311.pyc (limited to 'venv/lib/python3.11/site-packages/faker/providers/ssn/es_MX') diff --git a/venv/lib/python3.11/site-packages/faker/providers/ssn/es_MX/__init__.py b/venv/lib/python3.11/site-packages/faker/providers/ssn/es_MX/__init__.py new file mode 100644 index 0000000..02e6481 --- /dev/null +++ b/venv/lib/python3.11/site-packages/faker/providers/ssn/es_MX/__init__.py @@ -0,0 +1,261 @@ +""" +SSN provider for es_MX. + +This module adds a provider for mexican SSN, along with Unique Population +Registry Code (CURP) and Federal Taxpayer Registry ID (RFC). +""" + +import random +import string + +from typing import Optional + +from .. import Provider as BaseProvider + +try: + from typing import Literal # type: ignore +except ImportError: + from typing_extensions import Literal # type: ignore + + +ALPHABET = string.ascii_uppercase +ALPHANUMERIC = string.digits + ALPHABET +VOWELS = "AEIOU" +CONSONANTS = [letter for letter in ALPHABET if letter not in VOWELS] + +# https://es.wikipedia.org/wiki/Plantilla:Abreviaciones_de_los_estados_de_M%C3%A9xico +STATES_RENAPO = [ + "AS", + "BC", + "BS", + "CC", + "CS", + "CH", + "DF", + "CL", + "CM", + "DG", + "GT", + "GR", + "HG", + "JC", + "MC", + "MN", + "MS", + "NT", + "NL", + "OC", + "PL", + "QO", + "QR", + "SP", + "SL", + "SR", + "TC", + "TS", + "TL", + "VZ", + "YN", + "ZS", + "NE", # Foreign Born +] + +FORBIDDEN_WORDS = { + "BUEI": "BUEX", + "BUEY": "BUEX", + "CACA": "CACX", + "CACO": "CACX", + "CAGA": "CAGX", + "CAGO": "CAGX", + "CAKA": "CAKX", + "CAKO": "CAKX", + "COGE": "COGX", + "COJA": "COJX", + "COJE": "COJX", + "COJI": "COJX", + "COJO": "COJX", + "CULO": "CULX", + "FETO": "FETX", + "GUEY": "GUEX", + "JOTO": "JOTX", + "KACA": "KACX", + "KACO": "KACX", + "KAGA": "KAGX", + "KAGO": "KAGX", + "KOGE": "KOGX", + "KOJO": "KOJX", + "KAKA": "KAKX", + "KULO": "KULX", + "MAME": "MAMX", + "MAMO": "MAMX", + "MEAR": "MEAX", + "MEAS": "MEAX", + "MEON": "MEOX", + "MION": "MIOX", + "MOCO": "MOCX", + "MULA": "MULX", + "PEDA": "PEDX", + "PEDO": "PEDX", + "PENE": "PENX", + "PUTA": "PUTX", + "PUTO": "PUTX", + "QULO": "QULX", + "RATA": "RATX", + "RUIN": "RUIN", +} + +CURP_CHARACTERS = "0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ" + + +def _reduce_digits(number: int) -> int: + """ + Sum of digits of a number until sum becomes single digit. + + Example: + 658 => 6 + 5 + 8 = 19 => 1 + 9 = 10 => 1 + """ + if number == 0: + return 0 + if number % 9 == 0: + return 9 + + return number % 9 + + +def ssn_checksum(digits: map) -> int: + """ + Calculate the checksum for the mexican SSN (IMSS). + """ + return -sum(_reduce_digits(n * (i % 2 + 1)) for i, n in enumerate(digits)) % 10 + + +def curp_checksum(characters: str) -> int: + """ + Calculate the checksum for the mexican CURP. + """ + start = 18 + return -sum((start - i) * CURP_CHARACTERS.index(n) for i, n in enumerate(characters)) % 10 + + +class Provider(BaseProvider): + """ + A Faker provider for the Mexican SSN, RFC and CURP + """ + + ssn_formats = ("###########",) + + def ssn(self) -> str: + """ + Mexican Social Security Number, as given by IMSS. + + :return: a random Mexican SSN + """ + office = self.random_int(min=1, max=99) + birth_year = self.random_int(min=0, max=99) + start_year = self.random_int(min=0, max=99) + serial = self.random_int(min=1, max=9999) + + num = f"{office:02d}{start_year:02d}{birth_year:02d}{serial:04d}" + + check = ssn_checksum(map(int, num)) + num += str(check) + + return num + + def curp(self) -> str: + """ + See https://es.wikipedia.org/wiki/Clave_%C3%9Anica_de_Registro_de_Poblaci%C3%B3n. + + :return: a random Mexican CURP (Unique Population Registry Code) + """ + birthday = self.generator.date_of_birth() + + first_surname = random.choice(ALPHABET) + random.choice(VOWELS) + second_surname = random.choice(ALPHABET) + given_name = random.choice(ALPHABET) + name_initials = first_surname + second_surname + given_name + + birth_date = birthday.strftime("%y%m%d") + gender = random.choice("HM") + state = random.choice(STATES_RENAPO) + first_surname_inside = random.choice(CONSONANTS) + second_surname_inside = random.choice(CONSONANTS) + given_name_inside = random.choice(ALPHABET) + + # This character is assigned to avoid duplicity + # It's normally '0' for those born < 2000 + # and 'A' for those born >= 2000 + assigned_character = "0" if birthday.year < 2000 else "A" + + name_initials = FORBIDDEN_WORDS.get(name_initials, name_initials) + + random_curp = ( + name_initials + + birth_date + + gender + + state + + first_surname_inside + + second_surname_inside + + given_name_inside + + assigned_character + ) + + random_curp += str(curp_checksum(random_curp)) + + return random_curp + + def rfc(self, natural: bool = True) -> str: + """ + See https://es.wikipedia.org/wiki/Registro_Federal_de_Contribuyentes + + :param natural: Whether to return the RFC of a natural person. + Otherwise return the RFC of a legal person. + :type natural: bool + :return: a random Mexican RFC + """ + birthday = self.generator.date_of_birth() + + if natural: + first_surname = random.choice(ALPHABET) + random.choice(VOWELS) + second_surname = random.choice(ALPHABET) + given_name = random.choice(ALPHABET) + name_initials = first_surname + second_surname + given_name + name_initials = FORBIDDEN_WORDS.get(name_initials, name_initials) + else: + name_initials = ( + self.random_uppercase_letter() + self.random_uppercase_letter() + self.random_uppercase_letter() + ) + + birth_date = birthday.strftime("%y%m%d") + disambiguation_code = random.choice(ALPHANUMERIC) + random.choice(ALPHANUMERIC) + random.choice(ALPHANUMERIC) + + random_rfc = name_initials + birth_date + disambiguation_code + + return random_rfc + + def elector_code(self, gender: Optional[Literal["H", "M"]] = None) -> str: + """ + Unique elector code issued by INE (Instituto Nacional Electoral) in Mexico. + + :param gender: Gender for which to generate the code. Will be randomly + selected if not provided. + :type gender: str + :return: a random INE elector code + + :sample: + :sample: gender='M' + """ + if gender and gender not in ("H", "M"): + raise ValueError("Gender must be 'H' or 'M'") + + gender = gender or random.choice(["H", "M"]) + + consonants = "".join(random.choices(CONSONANTS, k=6)) + + birthday = self.generator.date_of_birth() + birth_date = birthday.strftime("%y%m%d") + + entity = random.randint(1, 33) + disambiguation_code = "".join(random.choices(string.digits, k=3)) + + return f"{consonants}{birth_date}{entity:02d}{gender}{disambiguation_code}" diff --git a/venv/lib/python3.11/site-packages/faker/providers/ssn/es_MX/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/faker/providers/ssn/es_MX/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..acb2f5d Binary files /dev/null and b/venv/lib/python3.11/site-packages/faker/providers/ssn/es_MX/__pycache__/__init__.cpython-311.pyc differ -- cgit v1.2.3