update bots

This commit is contained in:
2026-05-18 14:15:59 +07:00
parent b0ce866a2f
commit b9054d178e
5775 changed files with 832577 additions and 38 deletions

View File

@@ -0,0 +1,10 @@
from .. import BaseProvider, ElementsType
localized = True
class Provider(BaseProvider):
ssn_formats: ElementsType[str] = ("###-##-####",)
def ssn(self) -> str:
return self.bothify(self.random_element(self.ssn_formats))

View File

@@ -0,0 +1,43 @@
from .. import Provider as SsnProvider
class Provider(SsnProvider):
"""
Sources:
- https://fr.wikipedia.org/wiki/Num%C3%A9ro_d%27identification_national_(Alg%C3%A9rie)
- https://github.com/itshakim213/dz-nin-checker
"""
def _control_key(self, base: str) -> str:
"""Compute the 2-digit control key via modified Luhn over 16 digits."""
total, alternate = 0, False
for i in range(len(base) - 1, -1, -1):
d = int(base[i]) * (2 if alternate else 1)
total += d - 9 if d > 9 else d
alternate = not alternate
remainder = total % 10
return f"{(0 if remainder == 0 else 10 - remainder):02d}"
def ssn(self) -> str:
"""Generate an Algerian National Identification Number (NIN).
Structure (18 digits):
- 1 digit nationality: ``1`` = Algerian, ``2`` = dual nationality
- 1 digit sex: ``0`` = male, ``1`` = female
- 3 digits last three digits of the birth-registration year
- 4 digits commune code (wilaya 0158 + commune 0120)
- 5 digits birth-certificate act number
- 2 digits annual register serial number
- 2 digits control key (modified Luhn)
"""
nationality = self.random_element(("1", "2"))
sex = self.random_element(("0", "1"))
year_code = f"{self.random_int(min=1950, max=2006) % 1000:03d}"
wilaya = self.random_int(min=1, max=58)
commune_code = f"{wilaya:02d}{self.random_int(min=1, max=20):02d}"
act_code = f"{self.random_int(min=1, max=99999):05d}"
register_code = f"{self.random_int(min=1, max=99):02d}"
base = nationality + sex + year_code + commune_code + act_code + register_code
return base + self._control_key(base)

View File

@@ -0,0 +1,39 @@
from .. import Provider as SsnProvider
class Provider(SsnProvider):
# The FIN code consists of 7 characters (letters and numbers of the English alphabet,
# except for the letters "I" and "O").
characters = [
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"J",
"K",
"L",
"M",
"N",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
]
numbers = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
all_characters = characters + numbers
def ssn(self) -> str:
ssn = "".join(self.random_elements(elements=self.all_characters, length=7))
return ssn

View File

@@ -0,0 +1,20 @@
from .. import Provider as BaseProvider
class Provider(BaseProvider):
"""
A Faker provider for the Bulgarian VAT IDs
"""
vat_id_formats = (
"BG#########",
"BG##########",
)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: A random Bulgarian VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,15 @@
from .. import Provider as SsnProvider
class Provider(SsnProvider):
"""
Implement SSN provider for ``bn_BD`` locale.
National ID Card Number is considered the SSN number for
Bangladeshi people.
:example: '1882824588423'
"""
ssn_formats = (
"%############",
"%## ### ####",
)

View File

@@ -0,0 +1,42 @@
from math import ceil
from typing import List, Tuple
from .. import Provider as BaseProvider
class Provider(BaseProvider):
vat_id_formats: Tuple[str, ...] = (
"CZ########",
"CZ#########",
"CZ##########",
)
national_id_months: List[str] = ["%.2d" % i for i in range(1, 13)] + ["%.2d" % i for i in range(51, 63)]
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: A random Czech VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))
def birth_number(self) -> str:
"""
Birth Number (Czech/Slovak: rodné číslo (RČ))
https://en.wikipedia.org/wiki/National_identification_number#Czech_Republic_and_Slovakia
"""
birthdate = self.generator.date_of_birth()
year = f"{birthdate:%y}"
month: str = self.random_element(self.national_id_months)
day = f"{birthdate:%d}"
if birthdate.year > 1953:
sn = self.random_number(4, True)
else:
sn = self.random_number(3, True)
number = int(f"{year}{month}{day}{sn}")
birth_number = str(ceil(number / 11) * 11)
if year == "00":
birth_number = "00" + birth_number
elif year[0] == "0":
birth_number = "0" + birth_number
return f"{birth_number[:6]}/{birth_number[6:]}"

View File

@@ -0,0 +1,48 @@
from datetime import date
from typing import List, Optional
from .. import Provider as BaseProvider
class Provider(BaseProvider):
"""
A Faker provider for the Austrian VAT IDs
"""
vat_id_formats = ("ATU########",)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: a random Austrian VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))
def __get_check_digit(self, ssn_without_checkdigit: str) -> int:
factors: List[int] = [3, 7, 9, 5, 8, 4, 2, 1, 6]
ssn_numbers: List[int] = [int(char) for char in ssn_without_checkdigit]
sum: int = 0
for index, factor in enumerate(factors):
sum += ssn_numbers[index] * factor
check_digit = sum % 11
return check_digit
def ssn(self, birthdate: Optional[date] = None) -> str:
"""
Source: https://de.wikipedia.org/wiki/Sozialversicherungsnummer#Berechnung
:return: a random valid Austrian social security number
"""
_birthdate = birthdate or self.generator.date_object()
format: str = f"%##{_birthdate:%d%m%y}"
ssn: str = self.numerify(format)
check_digit: int = self.__get_check_digit(ssn)
while check_digit > 9:
ssn = self.numerify(format)
check_digit = self.__get_check_digit(ssn)
return ssn[:3] + str(self.__get_check_digit(ssn)) + ssn[3:]

View File

@@ -0,0 +1,5 @@
from ..fr_CH import Provider as BaseProvider
class Provider(BaseProvider):
pass

View File

@@ -0,0 +1,100 @@
from datetime import date
from string import ascii_uppercase
from typing import Optional
from faker.utils.checksums import luhn_checksum
from .. import Provider as BaseProvider
class Provider(BaseProvider):
"""
A Faker provider for the German VAT ID and the pension insurance number
Sources:
- http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
- https://de.wikipedia.org/wiki/Versicherungsnummer
"""
vat_id_formats = ("DE#########",)
def __letter_to_digit_string(self, letter: str) -> str:
digit = ascii_uppercase.index(letter) + 1
if len(str(digit)) == 2:
return str(digit)
return "0" + str(digit)
def __get_rvnr_checkdigit(self, rvnr: str) -> str:
# replace the letter at index 8 with its corresponding number
letter = rvnr[8]
rvnr = rvnr[:8] + self.__letter_to_digit_string(letter) + rvnr[9:]
# calculate the product of each digit with the corresponding factor
factors = [2, 1, 2, 5, 7, 1, 2, 1, 2, 1, 2, 1]
products = []
for index, digit in enumerate(rvnr):
products.append(int(digit) * factors[index])
# calculate the digit sum for each product
digit_sums = []
for product in products:
digit_sum = 0
while product:
digit_sum += product % 10
product = product // 10
digit_sums.append(digit_sum)
# get the check digit by summing up the digit sums and calculating the modulo of 10
return str(sum(digit_sums) % 10)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: A random German VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))
def rvnr(self, birthdate: Optional[date] = None) -> str:
"""
Pension insurance number (German: "Rentenversicherungsnummer", abbr. "RVNR")
Source: https://de.wikipedia.org/wiki/Versicherungsnummer
:return: A valid German pension insurance number
"""
_birthdate = birthdate or self.generator.date_object()
format: str = f"##{_birthdate:%d%m%y}?##"
rvnr: str = self.bothify(format, letters=ascii_uppercase)
return rvnr + self.__get_rvnr_checkdigit(rvnr)
def kvnr(self) -> str:
"""
German health insurance number ("Krankenversichertennummer", abbr. "KVNR")
Source: https://de.wikipedia.org/wiki/Krankenversichertennummer
:return: a random health insurance number
"""
letter_number: str = str(self.random_int(min=1, max=26))
if len(letter_number) == 1:
letter_number = "0" + letter_number
first_part_format: str = letter_number + "########"
first_part: str = self.numerify(first_part_format)
first_checkdigit: int = luhn_checksum(int(first_part[::-1]))
second_part_format: str = "#########"
second_part: str = self.numerify(second_part_format)
kvnr: str = first_part + str(first_checkdigit) + second_part
kvnr_checkdigit: int = luhn_checksum(int(kvnr[::-1]))
kvnr = kvnr + str(kvnr_checkdigit)
letter: str = ascii_uppercase[int(letter_number) - 1]
kvnr = letter + kvnr[2:]
return kvnr

View File

@@ -0,0 +1,16 @@
from .. import Provider as BaseProvider
class Provider(BaseProvider):
"""
A Faker provider for the Danish VAT IDs
"""
vat_id_formats = ("DK########",)
def vat_id(self) -> str:
"""
Returns a random generated Danish Tax ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,16 @@
from .. import Provider as BaseProvider
class Provider(BaseProvider):
"""
A Faker provider for the Cypriot VAT IDs
"""
vat_id_formats = ("CY#########?",)
def vat_id(self) -> str:
"""
Returns a random generated Cypriot Tax ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,84 @@
import random
from faker.utils.checksums import calculate_luhn
from .. import Provider as BaseProvider
def tin_checksum(tin: str) -> int:
"""
Calculates the checksum (last) digit of Greek TINs given the rest
:param tin: first 8 digits of a Greek TIN
:return: calculated checksum digit
"""
tin_list = [int(i) for i in list(tin)]
return (
(
(tin_list[0] * 256)
+ (tin_list[1] * 128)
+ (tin_list[2] * 64)
+ (tin_list[3] * 32)
+ (tin_list[4] * 16)
+ (tin_list[5] * 8)
+ (tin_list[6] * 4)
+ (tin_list[7] * 2)
)
% 11
) % 10
class Provider(BaseProvider):
"""
A Faker provider for Greek identification numbers
"""
police_id_format = "??######"
# TIN checksum algo sourced from here
# http://epixeirisi.gr/%CE%9A%CE%A1%CE%99%CE%A3%CE%99%CE%9C%CE%91-%CE%98%CE%95%CE%9C%CE%91%CE%A4%CE%91-%CE%A6%CE%9F%CE%A1%CE%9F%CE%9B%CE%9F%CE%93%CE%99%CE%91%CE%A3-%CE%9A%CE%91%CE%99-%CE%9B%CE%9F%CE%93%CE%99%CE%A3%CE%A4%CE%99%CE%9A%CE%97%CE%A3/23791/%CE%91%CF%81%CE%B9%CE%B8%CE%BC%CF%8C%CF%82-%CE%A6%CE%BF%CF%81%CE%BF%CE%BB%CE%BF%CE%B3%CE%B9%CE%BA%CE%BF%CF%8D-%CE%9C%CE%B7%CF%84%CF%81%CF%8E%CE%BF%CF%85
def vat_id(self, prefix: bool = True) -> str:
"""
Generates random Greek VAT IDs (business TINs)
:param prefix: boolean option to use EU format ("EL") prefix
:return: a random Greek VAT ID
"""
vat_id = "EL" if prefix else ""
vat_id_starting_numbers = ("7", "8", "9", "0")
vat_id = vat_id + random.choice(vat_id_starting_numbers) + self.numerify("#######")
return vat_id + str(tin_checksum(vat_id[2:] if prefix else vat_id))
def tin(self) -> str:
"""
Generates random Greek personal TINs
:return: a random Greek personal TIN
"""
vat_id_starting_numbers = ("1", "2", "3", "4")
vat_id = random.choice(vat_id_starting_numbers) + self.numerify("#######")
return vat_id + str(tin_checksum(vat_id))
# Uses Luhn checksum according to this
# https://dotnetadventures.wordpress.com/2012/12/13/c-%CE%AD%CE%BB%CE%B5%CE%B3%CF%87%CE%BF%CF%82-%CE%BF%CF%81%CE%B8%CF%8C%CF%84%CE%B7%CF%84%CE%B1%CF%82-%CE%B1-%CE%BC-%CE%BA-%CE%B1-includes-python-version/
def ssn(self) -> str:
"""
Generates random Greek social security number (AMKA)
:return: a random Greek social security number
"""
ssn = self.generator.date(pattern="%d%m%y") + self.numerify("####")
return ssn + str(calculate_luhn(ssn))
# Valid format accd to ΥΑ 3021/19/53/2005 - FΕΚ 1440/Β'/18.10.2005
# http://www.dsanet.gr/Epikairothta/Nomothesia/ya3021_19_05.htm
def police_id(self) -> str:
"""
Generates random Greek identity card (aka police-issued identification card) numbers
:return: a random Greek identity card number
"""
return self.bothify(
self.police_id_format,
letters="ΑΒΕΖΗΙΚΜΝΟΡΤΥΧ",
)

View File

@@ -0,0 +1,80 @@
from .. import Provider as SsnProvider
def checksum(sin):
"""
Determine validity of a Canadian Social Insurance Number.
Validation is performed using a modified Luhn Algorithm. To check
the Every second digit of the SIN is doubled and the result is
summed. If the result is a multiple of ten, the Social Insurance
Number is considered valid.
https://en.wikipedia.org/wiki/Social_Insurance_Number
"""
# Remove spaces and create a list of digits.
checksumCollection = list(sin.replace(" ", ""))
checksumCollection = [int(i) for i in checksumCollection]
# Discard the last digit, we will be calculating it later.
checksumCollection[-1] = 0
# Iterate over the provided SIN and double every second digit.
# In the case that doubling that digit results in a two-digit
# number, then add the two digits together and keep that sum.
for i in range(1, len(checksumCollection), 2):
result = checksumCollection[i] * 2
if result < 10:
checksumCollection[i] = result
else:
checksumCollection[i] = result - 10 + 1
# The appropriate checksum digit is the value that, when summed
# with the first eight values, results in a value divisible by 10
check_digit = 10 - (sum(checksumCollection) % 10)
check_digit = 0 if check_digit == 10 else check_digit
return check_digit
class Provider(SsnProvider):
# In order to create a valid SIN we need to provide a number that
# passes a simple modified Luhn Algorithm checksum.
#
# This function reverses the checksum steps to create a random
# valid nine-digit Canadian SIN (Social Insurance Number) in the
# format '### ### ###'.
def ssn(self) -> str:
# Create an array of 8 elements initialized randomly.
digits = self.generator.random.sample(range(9), 8)
# The final step of the validation requires that all of the
# digits sum to a multiple of 10. First, sum the first 8 and
# set the 9th to the value that results in a multiple of 10.
check_digit = 10 - (sum(digits) % 10)
check_digit = 0 if check_digit == 10 else check_digit
digits.append(check_digit)
# digits is now the digital root of the number we want
# multiplied by the magic number 121 212 121. The next step is
# to reverse the multiplication which occurred on every other
# element.
for i in range(1, len(digits), 2):
if digits[i] % 2 == 0:
digits[i] = digits[i] // 2
else:
digits[i] = (digits[i] + 9) // 2
# Build the resulting SIN string.
sin = ""
for i in range(0, len(digits)):
sin += str(digits[i])
# Add a space to make it conform to Canadian formatting.
if i in (2, 5):
sin += " "
# Finally return our random but valid SIN.
return sin

View File

@@ -0,0 +1,39 @@
from typing import Tuple
from .. import Provider as BaseProvider
class Provider(BaseProvider):
# Source:
# https://en.wikipedia.org/wiki/National_Insurance_number
# UK National Insurance numbers (NINO) follow a specific format
# To avoid generating real NINOs, the prefix and suffix letters
# remain static using values reserved by HMRC (never to be used).
# Example format: "QR 12 34 56 C" or "QR123456C" - only alphanumeric
# and whitespace characters are permitted. Whitespace is for readability
# only and is generally included as per the above examples, but a
# few 'styles' have been included below for the sake of realism.
nino_formats: Tuple[str, ...] = (
"ZZ ## ## ## T",
"ZZ######T",
"ZZ ###### T",
)
def ssn(self) -> str:
pattern: str = self.random_element(self.nino_formats)
return self.numerify(self.generator.parse(pattern))
vat_id_formats: Tuple[str, ...] = (
"GB### #### ##",
"GB### #### ## ###",
"GBGD###",
"GBHA###",
)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: A random British VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,21 @@
from .. import Provider as BaseProvider
class Provider(BaseProvider):
"""
A Faker provider for the Irish VAT IDs
"""
vat_id_formats = (
"IE#?#####?",
"IE#######?",
"IE#######??",
)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: a random Irish VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,26 @@
from faker.utils import checksums
from .. import Provider as BaseProvider
class Provider(BaseProvider):
"""
Faker provider for Indian Identifiers
"""
aadhaar_id_formats = ("%##########",)
def aadhaar_id(self) -> str:
"""
Aadhaar is a 12 digit person identifier generated for residents of
India.
Details: https://en.wikipedia.org/wiki/Aadhaar
Official Website: https://uidai.gov.in/my-aadhaar/about-your-aadhaar.html
"""
aadhaar_digits = self.numerify(self.random_element(self.aadhaar_id_formats))
checksum = checksums.calculate_luhn(int(aadhaar_digits))
aadhaar_number = f"{aadhaar_digits}{checksum}"
return aadhaar_number

View File

@@ -0,0 +1,53 @@
from ... import BaseProvider
class Provider(BaseProvider):
"""
Provider for Philippine IDs that are related to social security
There is no unified social security program in the Philippines. Instead, the Philippines has a messy collection of
social programs and IDs that, when put together, serves as an analogue of other countries' social security program.
The government agencies responsible for these programs have relatively poor/outdated information and documentation
on their respective websites, so the sources section include third party "unofficial" information.
- Social Security System (SSS) - Social insurance program for workers in private, professional, and informal sectors
- Government Service Insurance System (GSIS) - Social insurance program for government employees
- Home Development Mutual Fund (popularly known as Pag-IBIG) - Socialized financial assistance and loaning program
- Philippine Health Insurance Corporation (PhilHealth) - Social insurance program for health care
- Unified Multi-Purpose ID (UMID) - Identity card with common reference number (CRN) that serves as a link to
the four previous programs and was planned to supersede the previous IDs, but
its future is now uncertain because of the upcoming national ID system
Sources:
- https://www.sss.gov.ph/sss/DownloadContent?fileName=SSSForms_UMID_Application.pdf
- https://www.gsis.gov.ph/active-members/benefits/ecard-plus/
- https://www.pagibigfund.gov.ph/DLForms/providentrelated/PFF039_MembersDataForm_V07.pdf
- https://filipiknow.net/is-umid-and-sss-id-the-same/
- https://filipiknow.net/philhealth-number/
- https://en.wikipedia.org/wiki/Unified_Multi-Purpose_ID
"""
sss_formats = ("##-#######-#",)
gsis_formats = ("###########",)
philhealth_formats = ("##-#########-#",)
pagibig_formats = ("####-####-####",)
umid_formats = ("####-#######-#",)
def sss(self) -> str:
return self.numerify(self.random_element(self.sss_formats))
def gsis(self) -> str:
return self.numerify(self.random_element(self.gsis_formats))
def pagibig(self) -> str:
return self.numerify(self.random_element(self.pagibig_formats))
def philhealth(self) -> str:
return self.numerify(self.random_element(self.philhealth_formats))
def umid(self) -> str:
return self.numerify(self.random_element(self.umid_formats))
def ssn(self) -> str:
# Use UMID as SSN in the interim till its deprecation
return self.umid()

View File

@@ -0,0 +1,235 @@
from typing import List
from .. import Provider as BaseProvider
class Provider(BaseProvider):
INVALID_SSN_TYPE = "INVALID_SSN"
SSN_TYPE = "SSN"
ITIN_TYPE = "ITIN"
EIN_TYPE = "EIN"
def itin(self) -> str:
"""Generate a random United States Individual Taxpayer Identification Number (ITIN).
An United States Individual Taxpayer Identification Number
(ITIN) is a tax processing number issued by the Internal
Revenue Service. It is a nine-digit number that always begins
with the number 9 and has a range of 70-88 in the fourth and
fifth digit. Effective April 12, 2011, the range was extended
to include 900-70-0000 through 999-88-9999, 900-90-0000
through 999-92-9999 and 900-94-0000 through 999-99-9999.
https://www.irs.gov/individuals/international-taxpayers/general-itin-information
"""
area = self.random_int(min=900, max=999)
serial = self.random_int(min=0, max=9999)
# The group number must be between 70 and 99 inclusively but not 89 or 93
group: int = self.random_element([x for x in range(70, 100) if x not in [89, 93]])
itin = f"{area:03d}-{group:02d}-{serial:04d}"
return itin
def ein(self) -> str:
"""Generate a random United States Employer Identification Number (EIN).
An United States An Employer Identification Number (EIN) is
also known as a Federal Tax Identification Number, and is
used to identify a business entity. EINs follow a format of a
two-digit prefix followed by a hyphen and a seven-digit sequence:
##-######
https://www.irs.gov/businesses/small-businesses-self-employed/employer-id-numbers
"""
# Only certain EIN Prefix values are assigned:
#
# https://www.irs.gov/businesses/small-businesses-self-employed/how-eins-are-assigned-and-valid-ein-prefixes
ein_prefix_choices: List[str] = [
"01",
"02",
"03",
"04",
"05",
"06",
"10",
"11",
"12",
"13",
"14",
"15",
"16",
"20",
"21",
"22",
"23",
"24",
"25",
"26",
"27",
"30",
"31",
"32",
"33",
"34",
"35",
"36",
"37",
"38",
"39",
"40",
"41",
"42",
"43",
"44",
"45",
"46",
"47",
"48",
"50",
"51",
"52",
"53",
"54",
"55",
"56",
"57",
"58",
"59",
"60",
"61",
"62",
"63",
"64",
"65",
"66",
"67",
"68",
"71",
"72",
"73",
"74",
"75",
"76",
"77",
"80",
"81",
"82",
"83",
"84",
"85",
"86",
"87",
"88",
"90",
"91",
"92",
"93",
"94",
"95",
"98",
"99",
]
ein_prefix: str = self.random_element(ein_prefix_choices)
sequence = self.random_int(min=0, max=9999999)
ein = f"{ein_prefix:s}-{sequence:07d}"
return ein
def invalid_ssn(self) -> str:
"""Generate a random invalid United States Social Security Identification Number (SSN).
Invalid SSNs have the following characteristics:
Cannot begin with the number 9
Cannot begin with 666 in positions 1 - 3
Cannot begin with 000 in positions 1 - 3
Cannot contain 00 in positions 4 - 5
Cannot contain 0000 in positions 6 - 9
https://www.ssa.gov/kc/SSAFactSheet--IssuingSSNs.pdf
Additionally, return an invalid SSN that is NOT a valid ITIN by excluding certain ITIN related "group" values
"""
itin_group_numbers = [
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
80,
81,
82,
83,
84,
85,
86,
87,
88,
90,
91,
92,
94,
95,
96,
97,
98,
99,
]
area = self.random_int(min=0, max=999)
if area < 900 and area not in {666, 0}:
random_group_or_serial = self.random_int(min=1, max=1000)
if random_group_or_serial <= 500:
group = 0
serial = self.random_int(0, 9999)
else:
group = self.random_int(0, 99)
serial = 0
elif area in {666, 0}:
group = self.random_int(0, 99)
serial = self.random_int(0, 9999)
else:
group = self.random_element([x for x in range(0, 100) if x not in itin_group_numbers])
serial = self.random_int(0, 9999)
invalid_ssn = f"{area:03d}-{group:02d}-{serial:04d}"
return invalid_ssn
def ssn(self, taxpayer_identification_number_type: str = SSN_TYPE) -> str:
"""Generate a random United States Taxpayer Identification Number of the specified type.
If no type is specified, a US SSN is returned.
"""
if taxpayer_identification_number_type == self.ITIN_TYPE:
return self.itin()
elif taxpayer_identification_number_type == self.EIN_TYPE:
return self.ein()
elif taxpayer_identification_number_type == self.INVALID_SSN_TYPE:
return self.invalid_ssn()
elif taxpayer_identification_number_type == self.SSN_TYPE:
# Certain numbers are invalid for United States Social Security
# Numbers. The area (first 3 digits) cannot be 666 or 900-999.
# The group number (middle digits) cannot be 00. The serial
# (last 4 digits) cannot be 0000.
area = self.random_int(min=1, max=899)
if area == 666:
area += 1
group = self.random_int(1, 99)
serial = self.random_int(1, 9999)
ssn = f"{area:03d}-{group:02d}-{serial:04d}"
return ssn
else:
raise ValueError(
"taxpayer_identification_number_type must be one of 'SSN', 'EIN', 'ITIN', or 'INVALID_SSN'."
)

View File

@@ -0,0 +1,9 @@
from ..es_ES import Provider as BaseProvider
class Provider(BaseProvider):
"""
A Faker provider for the Spanish VAT IDs and DOIs
"""
pass

View File

@@ -0,0 +1,67 @@
from itertools import cycle
from .. import Provider as BaseProvider
def rut_check_digit(number: int) -> str:
"""
Calculate the last character of a RUT number
:return: RUT check digit
"""
sum = 0
for factor in cycle(range(2, 8)):
if number == 0:
break
sum += factor * (number % 10)
number //= 10
mod = -sum % 11
if mod == 11:
return "0"
elif mod == 10:
return "K"
else:
return str(mod)
class Provider(BaseProvider):
"""
A Faker provider for the Chilean VAT IDs, also known as RUTs.
Sources:
- https://es.wikipedia.org/wiki/Rol_%C3%9Anico_Tributario - Definition and check digit calculation
- https://presslatam.cl/2018/04/el-problema-de-la-escasez-y-stock-disponible-de-los-ruts-en-chile/
paragraph 4, where known ranges are described.
"""
minimum_rut_person = 10
maximum_rut_person = 31999999
minimum_rut_company = 60000000
maximum_rut_company = 99999999
rut_format = "{:,d}-{:s}"
def person_rut(self) -> str:
"""
:return: a random Chilean RUT between a 10 and 31.999.999 range
"""
return self.rut(self.minimum_rut_person, self.maximum_rut_person)
def company_rut(self) -> str:
"""
:return: a random Chilean RUT between 60.000.000 and 99.999.999
"""
return self.rut(self.minimum_rut_company, self.maximum_rut_company)
def rut(self, min: int = minimum_rut_person, max: int = maximum_rut_company) -> str:
"""
Generates a RUT within the specified ranges, inclusive.
:param min: Minimum RUT to generate.
:param max: Maximum RUT to generate.
:return: a random Chilean RUT between 35.000.000 and 99.999.999
"""
digits = self.random_int(min, max)
check = rut_check_digit(digits)
return self.rut_format.format(digits, check).replace(",", ".")

View File

@@ -0,0 +1,72 @@
import operator
from collections import OrderedDict
from .. import Provider as BaseProvider
def nit_check_digit(nit: str) -> str:
"""
Calculate the check digit of a NIT.
The check digit is calculated by multiplying the reversed digits of a NIT
by (3, 7, 13, 17, 19, 23, 29, 37, 41, 43, 47, 53, 59, 67, 71), respectively,
adding the results and applying MOD 11. If the result is greater than or equal
to 2, the check digit is 11 minus the result. Otherwise, the check digit is the
result.
"""
reversed_nit = nit[::-1]
digits = (int(digit) for digit in reversed_nit)
multipliers = (3, 7, 13, 17, 19, 23, 29, 37, 41, 43, 47, 53, 59, 67, 71)
value = sum(map(operator.mul, digits, multipliers)) % 11
if value >= 2:
value = 11 - value
return str(value)
class Provider(BaseProvider):
nuip_formats = OrderedDict(
[
("10########", 0.25),
("11########", 0.25),
("12########", 0.1),
("%!######", 0.4),
]
)
legal_person_nit_formats = [
"8########",
"9########",
]
def nuip(self) -> str:
"""
https://es.wikipedia.org/wiki/C%C3%A9dula_de_Ciudadan%C3%ADa_(Colombia)
:example: '1095312769'
"""
return self.numerify(self.random_element(self.nuip_formats))
natural_person_nit = nuip
def natural_person_nit_with_check_digit(self) -> str:
"""
:example: '1095312769-0'
"""
nit = self.natural_person_nit()
check_digit = nit_check_digit(nit)
return f"{nit}-{check_digit}"
def legal_person_nit(self) -> str:
"""
https://es.wikipedia.org/wiki/N%C3%BAmero_de_Identificaci%C3%B3n_Tributaria
:example: '967807269'
"""
return self.numerify(self.random_element(self.legal_person_nit_formats))
def legal_person_nit_with_check_digit(self) -> str:
"""
:example: '967807269-7'
"""
nit = self.legal_person_nit()
check_digit = nit_check_digit(nit)
return f"{nit}-{check_digit}"

View File

@@ -0,0 +1,123 @@
import random
from .. import Provider as BaseProvider
class Provider(BaseProvider):
"""
A Faker provider for the Spanish VAT IDs and DOIs
"""
vat_id_formats = (
"ES?########",
"ES########?",
"ES?#######?",
)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: a random Spanish VAT ID
:sample:
"""
return self.bothify(self.random_element(self.vat_id_formats))
def nie(self) -> str:
"""
https://es.wikipedia.org/wiki/N%C3%BAmero_de_identidad_de_extranjero
:return: a random Spanish NIE
:sample:
"""
first_chr = random.randrange(0, 3)
doi_body = str(random.randrange(0, 10000000)).zfill(7)
control = self._calculate_control_doi(str(first_chr) + doi_body)
return "XYZ"[first_chr] + doi_body + control
def nif(self) -> str:
"""
https://es.wikipedia.org/wiki/N%C3%BAmero_de_identificaci%C3%B3n_fiscal
:return: NIF
:sample:
"""
nie_body = str(random.randrange(0, 100000000)) # generate a number of a maximum of 8 characters long
return nie_body.zfill(8) + self._calculate_control_doi(nie_body)
def cif(self) -> str:
"""
https://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal
:return: a random Spanish CIF
:sample:
"""
first_chr = random.choice("ABCDEFGHJNPQRSUVW")
doi_body = str(random.randrange(0, 10000000)).zfill(7)
cif = first_chr + doi_body
return cif + self._calculate_control_cif(cif)
def nuss(self, company: bool = False) -> str:
"""
:param company: flag to indicate if we should generate a company NUSS
:return: a random Spanish Social Security Number (Número de la Seguridad Social)
:sample:
:sample: company=True
"""
nuss_body_length = 8
if company:
nuss_body_length = 7
province_digits = f"{random.choice(list(range(1, 54)) + [66]):02d}"
nuss_body = "".join(str(random.randint(0, 9)) for _ in range(nuss_body_length))
control_digits = f"{int(province_digits+nuss_body) % 97:02d}"
nuss = f"{province_digits}{nuss_body}{control_digits}"
return nuss
@staticmethod
def _calculate_control_doi(doi: str) -> str:
"""
Calculate the letter that corresponds to the end of a DOI
:param doi: calculated value so far needing a control character
:return: DOI control character
"""
lookup = "TRWAGMYFPDXBNJZSQVHLCKE"
return lookup[int(doi) % 23]
@classmethod
def _calculate_control_cif(cls, cif: str) -> str:
"""
Calculate the letter that corresponds to the end of a CIF
:param cif: calculated value so far needing a control character
:return: CIF control character
Code was converted from the minified js of: https://generadordni.es/
"""
sum_ = 0
first_chr, cif_value = cif[0], cif[1:]
for index, char in enumerate(cif_value):
if index % 2:
sum_ += int(char)
else:
sum_ += sum(map(int, str(int(char) * 2)))
if sum_ > 10:
sum_ = int(str(sum_)[-1])
else:
sum_ = sum_
sum_ = 10 - (sum_ % 10)
if first_chr in ["F", "J", "K", "N", "P", "Q", "R", "S", "U", "V", "W"]:
return chr(64 + sum_)
elif first_chr in ["A", "B", "C", "D", "E", "F", "G", "H", "L", "M"]:
if sum_ == 10:
sum_ = 0
return str(sum_)
else: # K, L, M # pragma: no cover
# Old format that is no longer used, here for full compatability
return cls._calculate_control_doi(cif) # pragma: no cover

View File

@@ -0,0 +1,255 @@
"""
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 Literal, Optional
from .. import Provider as BaseProvider
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}"

View File

@@ -0,0 +1,69 @@
import datetime
import operator
from typing import List
from .. import Provider as SsnProvider
def checksum(digits: List[int]) -> int:
"""Calculate checksum of Estonian personal identity code.
Checksum is calculated with "Modulo 11" method using level I or II scale:
Level I scale: 1 2 3 4 5 6 7 8 9 1
Level II scale: 3 4 5 6 7 8 9 1 2 3
The digits of the personal code are multiplied by level I scale and summed;
if remainder of modulo 11 of the sum is less than 10, checksum is the
remainder.
If remainder is 10, then level II scale is used; checksum is remainder if
remainder < 10 or 0 if remainder is 10.
See also https://et.wikipedia.org/wiki/Isikukood
"""
sum_mod11 = sum(map(operator.mul, digits, Provider.scale1)) % 11
if sum_mod11 < 10:
return sum_mod11
sum_mod11 = sum(map(operator.mul, digits, Provider.scale2)) % 11
return 0 if sum_mod11 == 10 else sum_mod11
class Provider(SsnProvider):
scale1 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 1)
scale2 = (3, 4, 5, 6, 7, 8, 9, 1, 2, 3)
def ssn(self, min_age: int = 16, max_age: int = 90) -> str:
"""
Returns 11 character Estonian personal identity code (isikukood, IK).
Age of person is between 16 and 90 years, based on local computer date.
This function assigns random sex to person.
An Estonian Personal identification code consists of 11 digits,
generally given without any whitespace or other delimiters.
The form is GYYMMDDSSSC, where G shows sex and century of birth (odd
number male, even number female, 1-2 19th century, 3-4 20th century,
5-6 21st century), SSS is a serial number separating persons born on
the same date and C a checksum.
https://en.wikipedia.org/wiki/National_identification_number#Estonia
"""
age = datetime.timedelta(days=self.generator.random.randrange(min_age * 365, max_age * 365))
birthday = datetime.date.today() - age
if birthday.year < 2000:
ik = self.generator.random.choice(("3", "4"))
elif birthday.year < 2100:
ik = self.generator.random.choice(("5", "6"))
else:
ik = self.generator.random.choice(("7", "8"))
ik += f"{birthday:%y%m%d}{self.generator.random.randrange(999):03}"
return ik + str(checksum([int(ch) for ch in ik]))
vat_id_formats = ("EE#########",)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: A random Estonian VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,67 @@
import datetime
from .. import Provider as SsnProvider
class Provider(SsnProvider):
def ssn(self, min_age: int = 0, max_age: int = 105, artificial: bool = False) -> str:
"""
Returns 11 character Finnish personal identity code (Henkilötunnus,
HETU, Swedish: Personbeteckning). This function assigns random
gender to person.
HETU consists of eleven characters of the form DDMMYYCZZZQ, where
DDMMYY is the date of birth, C the century sign, ZZZ the individual
number and Q the control character (checksum). The sign for the
century is either + (18001899), - (19001999), or A (20002099).
The individual number ZZZ is odd for males and even for females.
For people born in Finland its range is 002-899
(larger numbers may be used in special cases).
An example of a valid code is 311280-888Y.
https://en.wikipedia.org/wiki/National_identification_number#Finland
"""
def _checksum(hetu):
checksum_characters = "0123456789ABCDEFHJKLMNPRSTUVWXY"
return checksum_characters[int(hetu) % 31]
if min_age == max_age:
age = datetime.timedelta(days=min_age * 365)
else:
age = datetime.timedelta(days=self.generator.random.randrange(min_age * 365, max_age * 365))
birthday = datetime.date.today() - age
# format %y requires year >= 1900 on Windows
hetu_date = "%02d%02d%s" % (
birthday.day,
birthday.month,
str(birthday.year)[-2:],
)
range = (900, 999) if artificial is True else (2, 899)
suffix = str(self.generator.random.randrange(*range)).zfill(3)
checksum = _checksum(hetu_date + suffix)
separator = self._get_century_code(birthday.year)
hetu = "".join([hetu_date, separator, suffix, checksum])
return hetu
@staticmethod
def _get_century_code(year: int) -> str:
"""Returns the century code for a given year"""
if 2000 <= year < 3000:
separator = "A"
elif 1900 <= year < 2000:
separator = "-"
elif 1800 <= year < 1900:
separator = "+"
else:
raise ValueError("Finnish SSN do not support people born before the year 1800 or after the year 2999")
return separator
vat_id_formats = ("FI########",)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: A random Finnish VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,7 @@
from ..en_PH import Provider as EnPhSsnProvider
class Provider(EnPhSsnProvider):
"""No difference from SSN Provider for en_PH locale"""
pass

View File

@@ -0,0 +1,46 @@
from typing import List
from .. import Provider as SsnProvider
class Provider(SsnProvider):
ssn_formats = ("###.####.####.##",)
def ssn(self) -> str:
"""
Returns a 13 digits Swiss SSN named AHV (German) or
AVS (French and Italian)
See: http://www.bsv.admin.ch/themen/ahv/00011/02185/
"""
def _checksum(digits):
evensum = sum(digits[:-1:2])
oddsum = sum(digits[1::2])
return (10 - ((evensum + oddsum * 3) % 10)) % 10
digits: List[int] = [7, 5, 6]
# create an array of first 9 elements initialized randomly
digits += self.generator.random.sample(range(10), 9)
# determine the last digit to make it qualify the test
digits.append(_checksum(digits))
# repeat steps until it does qualify the test
digits_ = "".join([str(d) for d in digits])
return f"{digits_[:3]}.{digits_[3:7]}.{digits_[7:11]}.{digits_[11:]}"
def vat_id(self) -> str:
"""
:return: Swiss UID number
"""
def _checksum(digits):
code = ["8", "6", "4", "2", "3", "5", "9", "7"]
remainder = 11 - (sum(map(lambda x, y: int(x) * int(y), code, digits)) % 11)
if remainder == 10:
return 0
elif remainder == 11:
return 5
return remainder
vat_id: str = self.numerify("########")
return "CHE" + vat_id + str(_checksum(vat_id))

View File

@@ -0,0 +1,5 @@
from ..ar_DZ import Provider as ArDzSsnProvider
class Provider(ArDzSsnProvider):
pass

View File

@@ -0,0 +1,159 @@
from typing import Tuple
from .. import Provider as BaseProvider
def calculate_checksum(ssn_without_checksum: int) -> int:
return 97 - (ssn_without_checksum % 97)
class Provider(BaseProvider):
"""
A Faker provider for the French VAT IDs
"""
vat_id_formats = (
"FR?? #########",
"FR## #########",
"FR?# #########",
"FR#? #########",
)
# department id, municipality id, name of department, name of municipality
# department id + municipality id = INSEE code
departments_and_municipalities = (
# France métropolitaine = Mainland France
("01", "053", "Ain", "Bourg-en-Bresse"),
("02", "408", "Aisne", "Laon"),
("03", "190", "Allier", "Moulins"),
("04", "070", "Alpes-de-Haute-Provence", "Digne-les-Bains"),
("05", "061", "Hautes-Alpes", "Gap"),
("06", "088", "Alpes-Maritimes", "Nice"),
("07", "186", "Ardèche", "Orgnac-l'Aven"),
("08", "105", "Ardennes", "Charleville-Mézières"),
("09", "122", "Ariège", "Foix"),
("10", "387", "Aube", "Troyes"),
("11", "069", "Aude", "Carcassonne"),
("12", "202", "Aveyron", "Rodez"),
("13", "055", "Bouches-du-Rhône", "Marseille"),
("14", "118", "Calvados", "Caen"),
("15", "014", "Cantal", "Aurillac"),
("16", "015", "Charente", "Angoulême"),
("17", "300", "Charente-Maritime", "Rochelle"),
("18", "033", "Cher", "Bourges"),
("19", "272", "Corrèze", "Tulle"),
("21", "231", "Côte-d'Or,Côte-d'Or", "Dijon"),
("22", "278", "Côtes-d'Armor,Côtes-d'Armor", "Saint-Brieuc"),
("23", "096", "Creuse", "Guéret"),
("24", "322", "Dordogne", "Périgueux"),
("25", "056", "Doubs", "Besançon"),
("26", "362", "Drôme", "Valence"),
("27", "229", "Eure", "Évreux"),
("28", "085", "Eure-et-Loir", "Chartres"),
("29", "232", "Finistère", "Quimper"),
("30", "189", "Gard", "Nîmes"),
("31", "555", "Haute-Garonne", "Toulouse"),
("32", "013", "Gers", "Auch"),
("33", "063", "Gironde", "Bordeaux"),
("34", "172", "Hérault", "Montpellier"),
("35", "238", "Ille-et-Vilaine", "Rennes"),
("36", "044", "Indre,Indre", "Châteauroux"),
("37", "261", "Indre-et-Loire", "Tours"),
("38", "185", "Isère", "Grenoble"),
("39", "300", "Jura", "Lons-le-Saunier"),
("40", "192", "Landes", "Mont-de-Marsan"),
("41", "018", "Loir-et-Cher", "Blois"),
("42", "218", "Loire", "Saint-Étienne"),
("43", "157", "Haute-Loire", "Puy-en-Velay"),
("44", "109", "Loire-Atlantique", "Nantes"),
("45", "234", "Loiret", "Orléans"),
("46", "042", "Lot", "Cahors"),
("47", "001", "Lot-et-Garonne", "Agen"),
("48", "095", "Lozère", "Mende"),
("49", "007", "Maine-et-Loire", "Angers"),
("50", "502", "Manche", "Saint-Lô"),
("51", "108", "Marne", "Châlons-en-Champagne"),
("52", "121", "Haute-Marne", "Chaumont"),
("53", "130", "Mayenne", "Laval"),
("54", "395", "Meurthe-et-Moselle", "Nancy"),
("55", "029", "Meuse", "Bar-le-Duc"),
("56", "260", "Morbihan", "Vannes"),
("57", "463", "Moselle", "Metz"),
("58", "194", "Nièvre", "Nevers"),
("59", "350", "Nord", "Lille"),
("60", "057", "Oise", "Beauvais"),
("61", "001", "Orne", "Alençon"),
("62", "041", "Pas-de-Calais", "Arras"),
("63", "113", "Puy-de-Dôme", "Clermont-Ferrand"),
("64", "445", "Pyrénées-Atlantiques", "Pau"),
("65", "440", "Hautes-Pyrénées", "Tarbes"),
("66", "136", "Pyrénées-Orientales", "Perpignan"),
("67", "482", "Bas-Rhin", "Strasbourg"),
("68", "066", "Haut-Rhin", "Colmar"),
("69", "123", "Rhône", "Lyon"),
("70", "550", "Haute-Saône", "Vesoul"),
("71", "270", "Saône-et-Loire", "Mâcon"),
("72", "181", "Sarthe", "Mans"),
("73", "065", "Savoie", "Chambéry"),
("74", "010", "Haute-Savoie", "Annecy"),
("75", "056", "Paris", "Paris"),
("76", "540", "Seine-Maritime", "Rouen"),
("77", "288", "Seine-et-Marne", "Melun"),
("78", "646", "Yvelines", "Versailles"),
("79", "191", "Deux-Sèvres", "Niort"),
("80", "021", "Somme", "Amiens"),
("81", "004", "Tarn", "Albi"),
("82", "121", "Tarn-et-Garonne", "Montauban"),
("83", "137", "Var", "Toulon"),
("84", "007", "Vaucluse", "Avignon"),
("85", "191", "Vendée", "Roche-sur-Yon"),
("86", "194", "Vienne", "Poitiers"),
("87", "085", "Haute-Vienne", "Limoges"),
("88", "160", "Vosges", "Épinal"),
("89", "024", "Yonne", "Auxerre"),
("90", "010", "Territoire", "Belfort"),
("91", "228", "Essonne", "Évry-Courcouronnes"),
("92", "050", "Hauts-de-Seine", "Nanterre"),
("93", "008", "Seine-Saint-Denis", "Bobigny"),
("94", "028", "Val-de-Marne", "Créteil"),
("95", "500", "Val-d'Oise", "Pontoise"),
# DOM-TOM = Overseas France
("971", "05", "Guadeloupe", "Basse-Terre"),
("972", "09", "Martinique", "Fort-de-France"),
("973", "02", "Guyane", "Cayenne"),
("974", "11", "Réunion", "Saint-Denis"),
("976", "11", "Mayotte", "Mamoudzou"),
)
def ssn(self) -> str:
"""
Creates a French numéro de sécurité sociale
https://fr.wikipedia.org/wiki/Num%C3%A9ro_de_s%C3%A9curit%C3%A9_sociale_en_France#Signification_des_chiffres_du_NIR
https://www.comptavoo.com/Numero-Securite-sociale,348.html
:return: a French SSN
"""
gender_id = self.random_int(min=1, max=2)
year_of_birth = self.random_int(min=0, max=99)
month_of_birth = self.random_int(min=1, max=12)
department_and_municipality: Tuple[str, str, str, str] = self.random_element(
self.departments_and_municipalities,
)
code_department = department_and_municipality[0]
code_municipality = department_and_municipality[1]
order_number = self.random_int(min=1, max=999)
ssn_without_checksum = int(
f"{gender_id:01}{year_of_birth:02}{month_of_birth:02}{code_department}{code_municipality}{order_number:03}",
)
checksum = calculate_checksum(ssn_without_checksum)
return f"{ssn_without_checksum}{checksum:02}"
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: a random French VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,28 @@
from .. import Provider as SsnProvider
class Provider(SsnProvider):
def ssn(self) -> str:
"""
Returns an Israeli identity number, known as Teudat Zehut ("tz").
https://en.wikipedia.org/wiki/Israeli_identity_card
"""
newID = str(self.generator.random.randrange(111111, 99999999))
newID = newID.zfill(8)
theSum = 0
indexRange = [0, 2, 4, 6]
for i in indexRange:
digit = newID[i]
num = int(digit)
theSum = theSum + num
num = int(newID[i + 1]) * 2
if num > 9:
num = int(str(num)[0]) + int(str(num)[1])
theSum = theSum + num
lastDigit = theSum % 10
if lastDigit != 0:
lastDigit = 10 - lastDigit
return str(newID) + str(lastDigit)

View File

@@ -0,0 +1,49 @@
from typing import List
from .. import Provider as SsnProvider
def checksum(digits: List[int]) -> int:
"""
Calculate and return control digit for given list of digits based on
ISO7064, MOD 11,10 standard.
"""
remainder = 10
for digit in digits:
remainder = (remainder + digit) % 10
if remainder == 0:
remainder = 10
remainder = (remainder * 2) % 11
control_digit = 11 - remainder
if control_digit == 10:
control_digit = 0
return control_digit
class Provider(SsnProvider):
"""
The Personal identification number (Croatian: Osobni identifikacijski
broj or OIB) is a permanent national identification number of every
Croatian citizen and legal persons domiciled in the Republic of Croatia.
OIB consists of 11 digits which contain no personal information. The OIB
is constructed from ten randomly chosen digits and one digit control number
(international standard ISO 7064, module 11.10).
"""
def ssn(self) -> str:
digits = self.generator.random.sample(range(10), 10)
digits.append(checksum(digits))
return "".join(map(str, digits))
vat_id_formats = ("HR###########",)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: A random Croatian VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,135 @@
from functools import reduce
from math import fmod
from typing import Optional
from ....typing import SexLiteral
from .. import Provider as SsnProvider
def zfix(d: int) -> str:
return "0" + str(d) if d < 10 else str(d)
class Provider(SsnProvider):
def ssn(self, dob: Optional[str] = None, gender: Optional[SexLiteral] = None) -> str:
"""
Generates Hungarian SSN equivalent (személyazonosító szám or, colloquially, személyi szám)
:param dob: date of birth as a "YYMMDD" string - this determines the checksum regime and is also encoded
in the személyazonosító szám.
:type dob: str
:param gender: gender of the person - "F" for female, M for male.
:type gender: str
:return: személyazonosító szám in str format (11 digs)
:rtype: str
"""
# Hungarian SSNs consist of 11 decimal characters, of the following
# schema:
#
# M EEHHNN SSSK
# ↑ ↑ ↑ ↑
# gender bday ser check digit
#
#
# The M (gender) character
# ------------------------
#
# Born <= 1999 Born > 1999
# Male Female Male Female
# 1 2 3 4
#
# It also includes information on original citizenship,but this is
# ignored for the sake of simplicity.
#
# Birthday
# --------
#
# Simply encoded as EEHHNN.
#
#
# Serial
# ------
#
# These digits differentiate persons born on the same date.
#
#
# Check digit
# -----------
#
# For those born before 1996:
#
# k11 = (1k1 + 2k2 + 3k3... 10k10) mod 11
#
# That is, you multiply each digit with its ordinal, add it up and
# take it mod 11. After 1996:
#
# k11 = (10k1 + 9k2 + 8k3... 1k10) mod 11
#
if dob:
E = int(dob[0:2])
H = int(dob[2:4])
N = int(dob[4:6])
if E <= 17:
# => person born after '99 in all likelihood...
if gender:
if gender.upper() == "F":
M = 4
elif gender.upper() == "M":
M = 3
else:
raise ValueError("Unknown gender - specify M or F.")
else:
M = self.generator.random_int(3, 4)
else:
# => person born before '99.
if gender:
if gender.upper() == "F":
M = 2
elif gender.upper() == "M":
M = 1
else:
raise ValueError("Unknown gender - specify M or F.")
else:
M = self.generator.random_int(1, 2)
elif gender:
# => assume statistically that the person will be born before '99.
E = self.generator.random_int(17, 99)
H = self.generator.random_int(1, 12)
N = self.generator.random_int(1, 30)
if gender.upper() == "F":
M = 2
elif gender.upper() == "M":
M = 1
else:
raise ValueError("Unknown gender - specify M or F")
else:
M = self.generator.random_int(1, 2)
E = self.generator.random_int(17, 99)
H = self.generator.random_int(1, 12)
N = self.generator.random_int(1, 30)
H_, N_ = zfix(H), zfix(N)
S = f"{self.generator.random_digit()}{self.generator.random_digit()}{self.generator.random_digit()}"
vdig = f"{M}{E}{H_}{N_}{S}"
if 17 < E < 97:
cum = [(k + 1) * int(v) for k, v in enumerate(vdig)]
else:
cum = [(10 - k) * int(v) for k, v in enumerate(vdig)]
K = fmod(reduce(lambda x, y: x + y, cum), 11)
return vdig + str(int(K))
vat_id_formats = ("HU########",)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: A random Hungarian VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
from .. import Provider as SsnProvider
class Provider(SsnProvider):
ssn_formats = (
"##0#0#-1######",
"##0#1#-1######",
"##0#2#-1######",
"##0#0#-2######",
"##0#1#-2######",
"##0#2#-2######",
)

View File

@@ -0,0 +1,17 @@
from .. import Provider as BaseProvider
class Provider(BaseProvider):
"""
A Faker provider for the Luxembourgish VAT IDs
"""
vat_id_formats = ("LU########",)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: a random Luxembourgish VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,20 @@
from .. import Provider as BaseProvider
class Provider(BaseProvider):
"""
A Faker provider for the Lithuanian VAT IDs
"""
vat_id_formats = (
"LT#########",
"LT############",
)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: a random Lithuanian VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,62 @@
import datetime
from .. import Provider as SsnProvider
class Provider(SsnProvider):
def ssn(self, min_age: int = 0, max_age: int = 105) -> str:
"""
Returns 11 character Latvian personal identity code (Personas kods).
This function assigns random age to person.
Personal code consists of eleven characters of the form DDMMYYCZZZQ, where
DDMMYY is the date of birth, C the century sign, ZZZ the individual
number and Q the control character (checksum). The number for the
century is either 0 (18001899), 1 (19001999), or 2 (20002099).
"""
def _checksum(ssn_without_checksum):
weights = [1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
weighted_sum = sum(int(digit) * weight for digit, weight in zip(ssn_without_checksum, weights))
reminder = (1 - weighted_sum) % 11
if reminder == 10:
return 0
elif reminder < -1:
return reminder + 11
return reminder
age = datetime.timedelta(days=self.generator.random.randrange(min_age * 365, max_age * 365))
birthday = datetime.date.today() - age
ssn_date = f"{birthday:%d%m%y}"
century = self._get_century_code(birthday.year) # Century
suffix = self.generator.random.randrange(111, 999)
checksum = _checksum(f"{ssn_date}{century:01d}{suffix:03d}")
ssn = f"{ssn_date}-{century:01d}{suffix:03d}{checksum:01d}"
return ssn
@staticmethod
def _get_century_code(year: int) -> int:
"""Returns the century code for a given year"""
if 2000 <= year < 3000:
code = 2
elif 1900 <= year < 2000:
code = 1
elif 1800 <= year < 1900:
code = 0
else:
raise ValueError("SSN do not support people born before the year 1800 or after the year 2999")
return code
"""
A Faker provider for the Latvian VAT IDs
"""
vat_id_formats = ("LV###########",)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: a random Latvian VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,17 @@
from .. import Provider as BaseProvider
class Provider(BaseProvider):
"""
A Faker provider for the Maltese VAT IDs
"""
vat_id_formats = ("MT########",)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: A random Maltese VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,74 @@
from .. import Provider as SsnProvider
"""
For more info on rijksregisternummer, see https://nl.wikipedia.org/wiki/Rijksregisternummer
Dutch/French only for now ...
"""
class Provider(SsnProvider):
def ssn(self) -> str:
"""
Returns a 11 digits Belgian SSN called "rijksregisternummer" as a string
The first 6 digits represent the birthdate with (in order) year, month and day.
The second group of 3 digits is represents a sequence number (order of birth).
It is even for women and odd for men.
For men the range starts at 1 and ends 997, for women 2 until 998.
The third group of 2 digits is a checksum based on the previous 9 digits (modulo 97).
Divide those 9 digits by 97, subtract the remainder from 97 and that's the result.
For persons born in or after 2000, the 9 digit number needs to be proceeded by a 2
(add 2000000000) before the division by 97.
"""
# see http://nl.wikipedia.org/wiki/Burgerservicenummer (in Dutch)
def _checksum(digits):
res = 97 - (digits % 97)
return res
# Generate a date (random)
mydate = self.generator.date()
# Convert it to an int
elms = mydate.split("-")
# Adjust for year 2000 if necessary
if elms[0][0] == "2":
above = True
else:
above = False
# Only keep the last 2 digits of the year
elms[0] = elms[0][2:4]
# Simulate the gender/sequence - should be 3 digits
seq = self.generator.random_int(1, 998)
# Right justify sequence and append to list
seq_str = f"{seq:0>3}"
elms.append(seq_str)
# Now convert list to an integer so the checksum can be calculated
date_as_int = int("".join(elms))
if above:
date_as_int += 2000000000
# Generate checksum
s = _checksum(date_as_int)
s_rjust = f"{s:0>2}"
# return result as a string
elms.append(s_rjust)
return "".join(elms)
vat_id_formats = ("BE##########",)
def vat_id(self) -> str:
vat_id_random_section = "#######"
vat_id_possible_initial_numbers = ("0", "1")
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
https://en.wikipedia.org/wiki/VAT_identification_number
:return: A random Belgian VAT ID starting with 0 or 1 and has a correct checksum with a modulo 97 check
"""
generated_initial_number: str = self.random_element(vat_id_possible_initial_numbers)
vat_without_check = self.bothify(f"{generated_initial_number}{vat_id_random_section}")
vat_as_int = int(vat_without_check)
vat_check = 97 - (vat_as_int % 97)
vat_check_str = f"{vat_check:0>2}"
return f"BE{vat_without_check}{vat_check_str}"

View File

@@ -0,0 +1,45 @@
from .. import Provider as SsnProvider
class Provider(SsnProvider):
def ssn(self) -> str:
"""
Returns a 9 digits Dutch SSN called "burgerservicenummer (BSN)".
the Dutch "burgerservicenummer (BSN)" needs to pass the "11-proef",
which is a check digit approach; this function essentially reverses
the checksum steps to create a random valid BSN (which is 9 digits).
"""
# see http://nl.wikipedia.org/wiki/Burgerservicenummer (in Dutch)
def _checksum(digits):
factors = (9, 8, 7, 6, 5, 4, 3, 2, -1)
s = 0
for i in range(len(digits)):
s += digits[i] * factors[i]
return s
while True:
# create an array of first 8 elements initialized randomly
digits = self.generator.random.sample(range(10), 8)
# sum those 8 digits according to (part of) the "11-proef"
s = _checksum(digits)
# determine the last digit to make it qualify the test
digits.append((s % 11) % 10)
# repeat steps until it does qualify the test
if 0 == (_checksum(digits) % 11):
break
# build the resulting BSN
bsn = "".join([str(e) for e in digits])
# finally return our random but valid BSN
return bsn
vat_id_formats = ("NL#########B##",)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: A random Dutch VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,83 @@
import datetime
import operator
from typing import List, Optional, Sequence
from ....typing import SexLiteral
from .. import Provider as SsnProvider
def checksum(digits: Sequence[int], scale: List[int]) -> int:
"""
Calculate checksum of Norwegian personal identity code.
Checksum is calculated with "Module 11" method using a scale.
The digits of the personal code are multiplied by the corresponding
number in the scale and summed;
if remainder of module 11 of the sum is less than 10, checksum is the
remainder.
If remainder is 0, the checksum is 0.
https://no.wikipedia.org/wiki/F%C3%B8dselsnummer
"""
chk_nbr = 11 - (sum(map(operator.mul, digits, scale)) % 11)
if chk_nbr == 11:
return 0
return chk_nbr
class Provider(SsnProvider):
scale1 = (3, 7, 6, 1, 8, 9, 4, 5, 2)
scale2 = (5, 4, 3, 2, 7, 6, 5, 4, 3, 2)
def ssn(self, dob: Optional[str] = None, gender: Optional[SexLiteral] = None) -> str:
"""
Returns 11 character Norwegian personal identity code (Fødselsnummer).
A Norwegian personal identity code consists of 11 digits, without any
whitespace or other delimiters. The form is DDMMYYIIICC, where III is
a serial number separating persons born oh the same date with different
intervals depending on the year they are born. CC is two checksums.
https://en.wikipedia.org/wiki/National_identification_number#Norway
:param dob: date of birth as a "YYYYMMDD" string
:type dob: str
:param gender: gender of the person - "F" for female, M for male.
:type gender: str
:return: Fødselsnummer in str format (11 digs)
:rtype: str
"""
if dob:
birthday = datetime.datetime.strptime(dob, "%Y%m%d")
else:
age = datetime.timedelta(days=self.generator.random.randrange(18 * 365, 90 * 365))
birthday = datetime.datetime.now() - age
if not gender:
gender = self.generator.random.choice(("F", "M"))
elif gender not in ("F", "M"):
raise ValueError("Gender must be one of F or M.")
while True:
if 1900 <= birthday.year <= 1999:
suffix = self.generator.random.randrange(0, 49)
elif 1854 <= birthday.year <= 1899:
suffix = self.generator.random.randrange(50, 74)
elif 2000 <= birthday.year <= 2039:
suffix = self.generator.random.randrange(50, 99)
elif 1940 <= birthday.year <= 1999:
suffix = self.generator.random.randrange(90, 99)
if gender == "F":
gender_num = self.generator.random.choice((0, 2, 4, 6, 8))
elif gender == "M":
gender_num = self.generator.random.choice((1, 3, 5, 7, 9))
pnr = f"{birthday:%d%m%y}{suffix:02}{gender_num}"
pnr_nums = [int(ch) for ch in pnr]
k1 = checksum(Provider.scale1, pnr_nums)
k2 = checksum(Provider.scale2, pnr_nums + [k1])
# Checksums with a value of 10 is rejected.
# https://no.wikipedia.org/wiki/F%C3%B8dselsnummer
if k1 == 10 or k2 == 10:
continue
pnr += f"{k1}{k2}"
return pnr

View File

@@ -0,0 +1,65 @@
from datetime import datetime
from typing import List
from .. import Provider as SsnProvider
def checksum(digits: List[int]) -> int:
"""
Calculates and returns a control digit for given list of digits basing on PESEL standard.
"""
weights_for_check_digit = [9, 7, 3, 1, 9, 7, 3, 1, 9, 7]
check_digit = 0
for i in range(0, 10):
check_digit += weights_for_check_digit[i] * digits[i]
check_digit %= 10
return check_digit
def calculate_month(birth_date: datetime) -> int:
"""
Calculates and returns a month number basing on PESEL standard.
"""
month = birth_date.month + ((birth_date.year // 100 - 14) % 5) * 20
return month
class Provider(SsnProvider):
def ssn(self) -> str:
"""
Returns 11 character Polish national identity code (Public Electronic Census System,
Polish: Powszechny Elektroniczny System Ewidencji Ludności - PESEL).
It has the form YYMMDDZZZXQ, where YYMMDD is the date of birth (with century
encoded in month field), ZZZ is the personal identification number, X denotes sex
(even for females, odd for males) and Q is a parity number.
https://en.wikipedia.org/wiki/National_identification_number#Poland
"""
birth_date = self.generator.date_time()
pesel_digits = [
*divmod(birth_date.year % 100, 10),
*divmod(calculate_month(birth_date), 10),
*divmod(birth_date.day, 10),
]
for _ in range(4):
pesel_digits.append(self.random_digit())
pesel_digits.append(checksum(pesel_digits))
return "".join(str(digit) for digit in pesel_digits)
vat_id_formats = ("PL##########",)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: A random Polish VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,64 @@
from typing import List
from .. import Provider as SsnProvider
def checksum(digits: List[int]) -> int:
"""
Returns the checksum of CPF digits.
References to the algorithm:
https://pt.wikipedia.org/wiki/Cadastro_de_pessoas_f%C3%ADsicas#Algoritmo
https://metacpan.org/source/MAMAWE/Algorithm-CheckDigits-v1.3.0/lib/Algorithm/CheckDigits/M11_004.pm
"""
s = 0
p = len(digits) + 1
for i in range(0, len(digits)):
s += digits[i] * p
p -= 1
reminder = s % 11
if reminder == 0 or reminder == 1:
return 0
else:
return 11 - reminder
class Provider(SsnProvider):
"""
Provider for Brazilian SSN also known in Brazil as CPF.
There are two methods Provider.ssn and Provider.cpf
The snn returns a valid number with numbers only
The cpf return a valid number formatted with brazilian mask. eg nnn.nnn.nnn-nn
"""
def ssn(self) -> str:
digits = self.generator.random.sample(range(10), 9)
dv = checksum(digits)
digits.append(dv)
digits.append(checksum(digits))
return "".join(map(str, digits))
def cpf(self) -> str:
c = self.ssn()
return c[:3] + "." + c[3:6] + "." + c[6:9] + "-" + c[9:]
def rg(self) -> str:
"""
Brazilian RG, return plain numbers.
Check: https://www.ngmatematica.com/2014/02/como-determinar-o-digito-verificador-do.html
"""
digits = self.generator.random.sample(range(0, 9), 8)
checksum = sum(i * digits[i - 2] for i in range(2, 10))
last_digit = 11 - (checksum % 11)
if last_digit == 10:
digits.append("X")
elif last_digit == 11:
digits.append(0)
else:
digits.append(last_digit)
return "".join(map(str, digits))

View File

@@ -0,0 +1,17 @@
from .. import Provider as BaseProvider
class Provider(BaseProvider):
"""
A Faker provider for the Portuguese VAT IDs
"""
vat_id_formats = ("PT#########",)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: A random Portuguese VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,135 @@
from .. import Provider as BaseProvider
def ssn_checksum(number: str) -> int:
"""
Calculate the checksum for the romanian SSN (CNP).
"""
weights = (2, 7, 9, 1, 4, 6, 3, 5, 8, 2, 7, 9)
check = sum(w * int(n) for w, n in zip(weights, number)) % 11
return 1 if check == 10 else check
def vat_checksum(number: str) -> int:
"""
Calculate the check digit for romanian VAT numbers.
"""
weights = (7, 5, 3, 2, 1, 7, 5, 3, 2)
number = (9 - len(number)) * "0" + number
check = 10 * sum(w * int(n) for w, n in zip(weights, number))
return check % 11 % 10
class Provider(BaseProvider):
"""
A Faker provider for the Romanian VAT IDs
"""
vat_id_formats = (
"RO1########",
"RO2########",
"RO3########",
"RO4########",
"RO5########",
"RO6########",
"RO7########",
"RO8########",
"RO9########",
"1########",
"2########",
"3########",
"4########",
"5########",
"6########",
"7########",
"8########",
"9########",
)
def vat_id(self) -> str:
"""
https://ro.wikipedia.org/wiki/Cod_de_identificare_fiscal%C4%83
:return: A random Romanian VAT ID
"""
vat = self.bothify(self.random_element(self.vat_id_formats))
coutry = ""
if vat.startswith("RO"):
coutry = "RO"
vat = vat[2:]
check = vat_checksum(vat)
vat += str(check)
return coutry + vat
ssn_formats = ("#############",)
def ssn(self) -> str:
"""
Romanian Social Security Number.
:return: a random Romanian SSN
"""
gender = self.random_int(min=1, max=8)
year = self.random_int(min=0, max=99)
month = self.random_int(min=1, max=12)
day = self.random_int(min=1, max=31)
county = int(
self.random_element(
[
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12",
"13",
"14",
"15",
"16",
"17",
"18",
"19",
"20",
"21",
"22",
"23",
"24",
"25",
"26",
"27",
"28",
"29",
"30",
"31",
"32",
"33",
"34",
"35",
"36",
"37",
"38",
"39",
"40",
"41",
"42",
"43",
"44",
"45",
"46",
"51",
"52",
]
)
)
serial = self.random_int(min=1, max=999)
num = f"{gender:01d}{year:02d}{month:02d}{day:02d}{county:02d}{serial:03d}"
check = ssn_checksum(num)
num += str(check)
return num

View File

@@ -0,0 +1,5 @@
from .. import Provider as SsnProvider
class Provider(SsnProvider):
ssn_formats = ("############",)

View File

@@ -0,0 +1,42 @@
from math import ceil
from .. import Provider as BaseProvider
class Provider(BaseProvider):
"""
A Faker provider for the Slovakian VAT IDs
"""
vat_id_formats = ("SK##########",)
national_id_months = ["%.2d" % i for i in range(1, 13)] + ["%.2d" % i for i in range(51, 63)]
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: a random Slovakian VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))
def birth_number(self) -> str:
"""
Birth Number (Czech/Slovak: rodné číslo (RČ))
https://en.wikipedia.org/wiki/National_identification_number#Czech_Republic_and_Slovakia
"""
birthdate = self.generator.date_of_birth()
year = f"{birthdate:%y}"
month: str = self.random_element(self.national_id_months)
day = f"{birthdate:%d}"
if birthdate.year > 1953:
sn = self.random_number(4, True)
else:
sn = self.random_number(3, True)
number = int(f"{year}{month}{day}{sn}")
birth_number = str(ceil(number / 11) * 11)
if year == "00":
birth_number = "00" + birth_number
elif year[0] == "0":
birth_number = "0" + birth_number
return f"{birth_number[:6]}/{birth_number[6::]}"

View File

@@ -0,0 +1,17 @@
from .. import Provider as BaseProvider
class Provider(BaseProvider):
"""
A Faker provider for the Slovenian VAT IDs
"""
vat_id_formats = ("SI########",)
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: a random Slovenian VAT ID
"""
return self.bothify(self.random_element(self.vat_id_formats))

View File

@@ -0,0 +1,86 @@
import datetime
import random
from typing import Tuple
from faker.utils.checksums import calculate_luhn
from .. import Provider as SsnProvider
class Provider(SsnProvider):
@staticmethod
def _org_to_vat(org_id: str) -> str:
org_id = org_id.replace("-", "")
if len(org_id) == 10:
org_id = "16" + org_id
return f"SE{org_id}01"
def ssn(
self,
min_age: int = 18,
max_age: int = 90,
long: bool = False,
dash: bool = True,
) -> str:
"""
Returns a 10 or 12 (long=True) digit Swedish SSN, "Personnummer".
It consists of 10 digits in the form (CC)YYMMDD-SSSQ, where
YYMMDD is the date of birth, SSS is a serial number
and Q is a control character (Luhn checksum).
Specifying dash=False will give a purely numeric string, suitable
for writing direct to databases.
http://en.wikipedia.org/wiki/Personal_identity_number_(Sweden)
"""
age = datetime.timedelta(days=self.generator.random.randrange(min_age * 365, max_age * 365))
birthday = datetime.datetime.now() - age
yr_fmt = "%Y" if long else "%y"
pnr_date = f"{birthday:{yr_fmt}%m%d}"
chk_date = pnr_date[2:] if long else pnr_date
suffix = f"{self.generator.random.randrange(0, 999):03}"
luhn_checksum = str(calculate_luhn(int(chk_date + suffix)))
hyphen = "-" if dash else ""
pnr = f"{pnr_date}{hyphen}{suffix}{luhn_checksum}"
return pnr
ORG_ID_DIGIT_1 = (1, 2, 3, 5, 6, 7, 8, 9)
def org_id(self, long: bool = False, dash: bool = True) -> str:
"""
Returns a 10 or 12 digit Organisation ID for a Swedish
company.
(In Swedish) https://sv.wikipedia.org/wiki/Organisationsnummer
"""
first_digits = list(self.ORG_ID_DIGIT_1)
random.shuffle(first_digits)
onr_one = str(first_digits.pop())
onr_one += str(self.generator.random.randrange(0, 9)).zfill(1)
onr_one += str(self.generator.random.randrange(20, 99))
onr_one += str(self.generator.random.randrange(0, 99)).zfill(2)
onr_two = str(self.generator.random.randrange(0, 999)).zfill(3)
luhn_checksum = str(calculate_luhn(int(onr_one + onr_two)))
prefix = "16" if long else ""
hyphen = "-" if dash else ""
org_id = f"{prefix}{onr_one}{hyphen}{onr_two}{luhn_checksum}"
return org_id
def vat_id(self) -> str:
"""
http://ec.europa.eu/taxation_customs/vies/faq.html#item_11
:return: A random Swedish VAT ID, based on a valid Org ID
"""
oid = self.org_id(long=True, dash=False)
vid = Provider._org_to_vat(oid)
return vid
def org_and_vat_id(self, long: bool = False, dash: bool = True) -> Tuple[str, str]:
"""Returns matching Org ID and VAT number"""
oid = self.org_id(long=long, dash=dash)
vid = Provider._org_to_vat(oid)
return oid, vid

View File

@@ -0,0 +1,59 @@
from random import randint
from .. import Provider as BaseProvider
class Provider(BaseProvider):
# Source:
# https://en.wikipedia.org/wiki/Thai_identity_card#Identification_number
# Thai national identity number has 13 digits, in this format:
# 1-2345-67890-12-3
# Digit 1: Person category
# Digits 2-5: Province and amphoe code of registrar's office (ISO 3166-2)
# Digits 6-12: Birth certificate number
# Digit 13: Checksum
def ssn(self) -> str:
"""
Thai national ID
"""
category = randint(1, 8)
province = randint(10, 96)
amphoe = 0
if province == 10: # Bangkok
amphoe = randint(1, 50) # Bangkok has district number up to 50
else:
amphoe = randint(1, 20) # Provinces outside Bangkok has 20 or less
birth_book = randint(1, 99999)
birth_sheet = randint(1, 99)
digits = f"{category:01d}{province:02d}{amphoe:02d}{birth_book:05d}{birth_sheet:02d}"
checksum = (
(int(digits[0]) * 13)
+ (int(digits[1]) * 12)
+ (int(digits[2]) * 11)
+ (int(digits[3]) * 10)
+ (int(digits[4]) * 9)
+ (int(digits[5]) * 8)
+ (int(digits[6]) * 7)
+ (int(digits[7]) * 6)
+ (int(digits[8]) * 5)
+ (int(digits[9]) * 4)
+ (int(digits[10]) * 3)
+ (int(digits[11]) * 2)
)
checksum = checksum % 11
checksum = 11 - checksum
if checksum > 9:
checksum = checksum - 10
nat_id = f"{category:01d}-{province:02d}{amphoe:02d}-{birth_book:05d}-{birth_sheet:02d}-{checksum:01d}"
return nat_id
def vat_id(self) -> str:
"""
Personal VAT ID is the same as national ID
(Corporate VAT ID is different)
"""
return self.ssn()

Some files were not shown because too many files have changed in this diff Show More