update bots
This commit is contained in:
@@ -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))
|
||||
Binary file not shown.
@@ -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 01–58 + commune 01–20)
|
||||
- 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)
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -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 = (
|
||||
"%############",
|
||||
"%## ### ####",
|
||||
)
|
||||
Binary file not shown.
@@ -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:]}"
|
||||
Binary file not shown.
@@ -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:]
|
||||
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
from ..fr_CH import Provider as BaseProvider
|
||||
|
||||
|
||||
class Provider(BaseProvider):
|
||||
pass
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -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="ΑΒΕΖΗΙΚΜΝΟΡΤΥΧ",
|
||||
)
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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()
|
||||
Binary file not shown.
@@ -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'."
|
||||
)
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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(",", ".")
|
||||
Binary file not shown.
@@ -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}"
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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}"
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -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 + (1800–1899), - (1900–1999), or A (2000–2099).
|
||||
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))
|
||||
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
from ..en_PH import Provider as EnPhSsnProvider
|
||||
|
||||
|
||||
class Provider(EnPhSsnProvider):
|
||||
"""No difference from SSN Provider for en_PH locale"""
|
||||
|
||||
pass
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
from ..ar_DZ import Provider as ArDzSsnProvider
|
||||
|
||||
|
||||
class Provider(ArDzSsnProvider):
|
||||
pass
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -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)
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -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######",
|
||||
)
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -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 (1800–1899), 1 (1900–1999), or 2 (2000–2099).
|
||||
"""
|
||||
|
||||
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))
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -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}"
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
from .. import Provider as SsnProvider
|
||||
|
||||
|
||||
class Provider(SsnProvider):
|
||||
ssn_formats = ("############",)
|
||||
Binary file not shown.
@@ -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::]}"
|
||||
Binary file not shown.
@@ -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))
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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()
|
||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user