diff --git a/drhider/checksum.py b/drhider/checksum.py new file mode 100644 index 0000000..733ef0f --- /dev/null +++ b/drhider/checksum.py @@ -0,0 +1,69 @@ +""" +Контрольные суммы для ИНН (10 и 12 знаков) и ОГРН. + +Используются генераторами фиктивных значений для создания +синтаксически корректных номеров. +""" + + +def checksum_inn10(inn: str) -> str: + """Контрольная сумма для 10-значного ИНН (юридические лица). + + Алгоритм: + 1. Умножаем первые 9 цифр на коэффициенты [2,4,10,3,5,9,4,6,8] + 2. Суммируем, берём (сумма % 11) % 10 + + Args: + inn: 9 цифр ИНН (без контрольной суммы) + + Returns: + Одна цифра контрольной суммы + """ + coeffs = [2, 4, 10, 3, 5, 9, 4, 6, 8] + s = sum(int(inn[i]) * coeffs[i] for i in range(9)) + return str((s % 11) % 10) + + +def checksum_inn12(inn: str) -> str: + """Контрольные суммы для 12-значного ИНН (физические лица). + + Алгоритм (две контрольные цифры): + 1. n1: умножаем первые 10 цифр на [7,2,4,10,3,5,9,4,6,8], + берём (сумма % 11) % 10 + 2. n2: добавляем n1 к числу, умножаем 11 цифр на + [3,7,2,4,10,3,5,9,4,6,8], берём (сумма % 11) % 10 + + Args: + inn: 10 цифр ИНН (без контрольных сумм) + + Returns: + Две цифры контрольных сумм (n1 + n2) + """ + c1 = [7, 2, 4, 10, 3, 5, 9, 4, 6, 8] + c2 = [3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8] + + # Первая контрольная цифра + s1 = sum(int(inn[i]) * c1[i] for i in range(10)) + n1 = (s1 % 11) % 10 + + # Вторая контрольная цифра (с учётом первой) + inn2 = inn + str(n1) + s2 = sum(int(inn2[i]) * c2[i] for i in range(11)) + n2 = (s2 % 11) % 10 + + return str(n1) + str(n2) + + +def checksum_ogrn(ogrn: str) -> str: + """Контрольная сумма для ОГРН (13 знаков). + + Алгоритм: первые 12 цифр как число % 11, затем % 10. + + Args: + ogrn: 12 цифр ОГРН (без контрольной суммы) + + Returns: + Одна цифра контрольной суммы + """ + s = int(ogrn) % 11 + return str(s % 10) diff --git a/drhider/config.py b/drhider/config.py new file mode 100644 index 0000000..79c2c70 --- /dev/null +++ b/drhider/config.py @@ -0,0 +1,88 @@ +""" +Константы и словари для DrHider. + +Содержит: +- ENTITY_PATTERNS — regex-паттерны для обнаружения сущностей +- COMPANY_PATTERN — паттерн для обнаружения названий компаний +- PERSON_PATTERN — паттерн для обнаружения ФИО +- Словари русских имён, городов, улиц +- Список фиктивных доменов для email +""" + +import re + +# ═══════════════════════════════════════════════════════════════════════════ +# Regex-паттерны для обнаружения сущностей в тексте документов +# ═══════════════════════════════════════════════════════════════════════════ + +ENTITY_PATTERNS = { + "phone": r'(? str: + """Сгенерировать фиктивный 20-значный расчётный счёт. + + Сохраняет оригинальный префикс (р/с, расчётный счёт и т.д.). + Начинается с 40702 (реальный префикс расчётного счёта). + + Args: + original: Оригинальная строка с расчётным счётом + + Returns: + Строка вида «р/с 40702XXXXXXXXXXXXXXX» + """ + prefix = re.match(r'(?:р/с|расч[её]тный\s*сч[её]т)\s*', original, re.IGNORECASE).group(0) + return prefix + "40702" + random_digits(15) + + +def generate_ks(original: str) -> str: + """Сгенерировать фиктивный 20-значный корреспондентский счёт. + + Сохраняет оригинальный префикс (к/с, кор/счёт и т.д.). + Начинается с 30101 (реальный префикс корр. счёта). + + Args: + original: Оригинальная строка с корр. счётом + + Returns: + Строка вида «к/с 30101XXXXXXXXXXXXXXX» + """ + prefix = re.match( + r'(?:к/с|кор/сч|корр?[еи]?спондентский\s*сч[её]т)\s*', + original, + re.IGNORECASE, + ).group(0) + return prefix + "30101" + random_digits(15) diff --git a/drhider/generators/address.py b/drhider/generators/address.py new file mode 100644 index 0000000..ecdc733 --- /dev/null +++ b/drhider/generators/address.py @@ -0,0 +1,25 @@ +""" +Генератор фиктивных почтовых адресов. + +Формат: Город, ул. Улица, д. Номер +""" + +import random +from ..config import RU_CITIES, RU_STREETS + + +def generate_address(_: str) -> str: + """Сгенерировать фиктивный почтовый адрес. + + Выбирает случайный город, улицу и номер дома из словарей. + + Args: + _: Оригинальный адрес (игнорируется) + + Returns: + Строка вида «Москва, ул. Ленина, д. 42» + """ + city = random.choice(RU_CITIES) + street = random.choice(RU_STREETS) + house = random.randint(1, 200) + return f"{city}, ул. {street}, д. {house}" diff --git a/drhider/generators/bik.py b/drhider/generators/bik.py new file mode 100644 index 0000000..d34e0ef --- /dev/null +++ b/drhider/generators/bik.py @@ -0,0 +1,25 @@ +""" +Генератор фиктивного БИК (9 знаков). + +Формат: «БИК » + 9 цифр. +Первые 2 цифры — 04 (код РФ). +""" + +import re +from ..random_utils import random_digits + + +def generate_bik(original: str) -> str: + """Сгенерировать фиктивный 9-значный БИК. + + Сохраняет оригинальный префикс (например, «БИК »). + Начинается с 04 (код Российской Федерации). + + Args: + original: Оригинальная строка с БИК + + Returns: + Строка вида «БИК 04XXXXXXX» + """ + prefix = re.match(r'БИК\s*', original, re.IGNORECASE).group(0) + return prefix + "04" + random_digits(7) diff --git a/drhider/generators/company.py b/drhider/generators/company.py new file mode 100644 index 0000000..a4bc310 --- /dev/null +++ b/drhider/generators/company.py @@ -0,0 +1,27 @@ +""" +Генератор фиктивных названий компаний. + +Формат: ООО/ЗАО/АО «СлучайноеСуществительное» +""" + +import random + + +def generate_company(_: str) -> str: + """Сгенерировать фиктивное название компании. + + Выбирает случайную организационно-правовую форму (ООО, ЗАО, АО) + и случайное существительное из словаря. + + Args: + _: Оригинальное название (игнорируется) + + Returns: + Строка вида «ООО «Технология»» + """ + forms = ["ООО", "ЗАО", "АО"] + nouns = [ + "Технология", "Прогресс", "Гарант", "Стандарт", "Импульс", + "Вектор", "Сфера", "Альянс", "Синтез", "Меридиан", "Спектр", "Формат", + ] + return f'{random.choice(forms)} «{random.choice(nouns)}»' diff --git a/drhider/generators/email.py b/drhider/generators/email.py new file mode 100644 index 0000000..fd40eb7 --- /dev/null +++ b/drhider/generators/email.py @@ -0,0 +1,23 @@ +""" +Генератор фиктивного email-адреса. + +Сохраняет структуру оригинального email: локальная_часть@домен. +""" + +import random +from ..config import FAKE_DOMAINS +from ..random_utils import random_letters + + +def generate_email(original: str) -> str: + """Сгенерировать фиктивный email с тем же форматом. + + Args: + original: Оригинальный email (для сохранения структуры, не используется) + + Returns: + Фиктивный email вида случайные_буквы@фиктивный_домен + """ + domain = random.choice(FAKE_DOMAINS) + local = random_letters(random.randint(5, 10)) + return f"{local}@{domain}" diff --git a/drhider/generators/inn.py b/drhider/generators/inn.py new file mode 100644 index 0000000..4c371e3 --- /dev/null +++ b/drhider/generators/inn.py @@ -0,0 +1,45 @@ +""" +Генераторы фиктивных ИНН. + +- generate_inn10: 10-значный ИНН (юридические лица) +- generate_inn12: 12-значный ИНН (физические лица) + +Оба сохраняют префикс «ИНН » и генерируют корректную контрольную сумму. +""" + +import random +import re +from ..random_utils import random_digits +from ..checksum import checksum_inn10, checksum_inn12 + + +def generate_inn10(original: str) -> str: + """Сгенерировать фиктивный 10-значный ИНН (для юридических лиц). + + Сохраняет оригинальный префикс (например, «ИНН »). + + Args: + original: Оригинальная строка с ИНН + + Returns: + Строка вида «ИНН XXXXXXXXX-C» с корректной контрольной суммой + """ + prefix = re.match(r'ИНН\s*', original, re.IGNORECASE).group(0) + base = f"{random.randint(1,9)}{random_digits(8)}" + return prefix + base + checksum_inn10(base) + + +def generate_inn12(original: str) -> str: + """Сгенерировать фиктивный 12-значный ИНН (для физических лиц). + + Сохраняет оригинальный префикс (например, «ИНН »). + + Args: + original: Оригинальная строка с ИНН + + Returns: + Строка вида «ИНН XXXXXXXXXX-CC» с двумя корректными контрольными суммами + """ + prefix = re.match(r'ИНН\s*', original, re.IGNORECASE).group(0) + base = f"{random.randint(1,9)}{random_digits(9)}" + return prefix + base + checksum_inn12(base) diff --git a/drhider/generators/kpp.py b/drhider/generators/kpp.py new file mode 100644 index 0000000..5bb9bd8 --- /dev/null +++ b/drhider/generators/kpp.py @@ -0,0 +1,26 @@ +""" +Генератор фиктивного КПП (9 знаков). + +Формат: «КПП » + 9 цифр. +Последние 3 цифры — код причины постановки (01, 43 или 77). +""" + +import random +import re +from ..random_utils import random_digits + + +def generate_kpp(original: str) -> str: + """Сгенерировать фиктивный 9-значный КПП. + + Сохраняет оригинальный префикс (например, «КПП »). + Последние 3 цифры — один из реальных кодов причины постановки. + + Args: + original: Оригинальная строка с КПП + + Returns: + Строка вида «КПП XXXX-код-XXX» + """ + prefix = re.match(r'КПП\s*', original, re.IGNORECASE).group(0) + return prefix + random_digits(4) + random.choice(["01", "43", "77"]) + random_digits(3) diff --git a/drhider/generators/ogrn.py b/drhider/generators/ogrn.py new file mode 100644 index 0000000..d279239 --- /dev/null +++ b/drhider/generators/ogrn.py @@ -0,0 +1,26 @@ +""" +Генератор фиктивного ОГРН (13 знаков). + +Формат: «ОГРН » + 13 цифр с корректной контрольной суммой. +""" + +import re +from ..random_utils import random_digits +from ..checksum import checksum_ogrn + + +def generate_ogrn(original: str) -> str: + """Сгенерировать фиктивный 13-значный ОГРН. + + Сохраняет оригинальный префикс (например, «ОГРН »). + Первая цифра всегда 1 (признак юридического лица). + + Args: + original: Оригинальная строка с ОГРН + + Returns: + Строка вида «ОГРН 1XXXXXXXXXXX-C» с корректной контрольной суммой + """ + prefix = re.match(r'ОГРН\s*', original, re.IGNORECASE).group(0) + base = "1" + random_digits(11) + return prefix + base + checksum_ogrn(base) diff --git a/drhider/generators/passport.py b/drhider/generators/passport.py new file mode 100644 index 0000000..8179fb2 --- /dev/null +++ b/drhider/generators/passport.py @@ -0,0 +1,26 @@ +""" +Генератор фиктивных паспортных данных. + +Формат: «паспорт » / «серия номер » + XX XX XXXXXX +""" + +import random +import re +from ..random_utils import random_digits + + +def generate_passport(original: str) -> str: + """Сгенерировать фиктивные паспортные данные. + + Сохраняет оригинальный префикс (паспорт, серия номер и т.д.). + Формат: 2 цифры серии + 2 цифры + 6 цифр номера. + + Args: + original: Оригинальная строка с паспортными данными + + Returns: + Строка вида «паспорт XX XX XXXXXX» + """ + m = re.match(r'(?:паспорт|серия\s+номер)[\s:№]*', original, re.IGNORECASE) + prefix = m.group(0) if m else "" + return prefix + f"{random.randint(10, 99)} {random.randint(10, 99)} {random_digits(6)}" diff --git a/drhider/generators/person.py b/drhider/generators/person.py new file mode 100644 index 0000000..fa6b66d --- /dev/null +++ b/drhider/generators/person.py @@ -0,0 +1,26 @@ +""" +Генератор фиктивных ФИО. + +Формат: Фамилия И.О. (фамилия полностью, имя и отчество — инициалы). +""" + +import random +from ..config import RU_SURNAMES, RU_NAMES, RU_PATRONYMICS + + +def generate_person(_: str) -> str: + """Сгенерировать фиктивное ФИО в формате «Фамилия И.О.». + + Выбирает случайные фамилию, имя и отчество из словарей. + Имя и отчество сокращаются до инициалов. + + Args: + _: Оригинальное ФИО (игнорируется) + + Returns: + Строка вида «Иванов А.И.» + """ + s = random.choice(RU_SURNAMES) + n = random.choice(RU_NAMES) + p = random.choice(RU_PATRONYMICS) + return f"{s} {n[0]}.{p[0]}." diff --git a/drhider/generators/phone.py b/drhider/generators/phone.py new file mode 100644 index 0000000..5e273ec --- /dev/null +++ b/drhider/generators/phone.py @@ -0,0 +1,22 @@ +""" +Генератор фиктивного телефонного номера. + +Формат: +7 (код) XXX-XX-XX +Код выбирается случайно из списка реальных российских кодов. +""" + +import random +from ..random_utils import random_digits + + +def generate_phone(_: str) -> str: + """Сгенерировать фиктивный российский телефонный номер. + + Args: + _: Оригинальный номер (игнорируется, нужен для единого интерфейса) + + Returns: + Строка в формате +7 (XXX) XXX-XX-XX + """ + code = random.choice(["495", "499", "812", "383", "343"]) + return f"+7 ({code}) {random_digits(3)}-{random_digits(2)}-{random_digits(2)}" diff --git a/drhider/random_utils.py b/drhider/random_utils.py new file mode 100644 index 0000000..ad87bfb --- /dev/null +++ b/drhider/random_utils.py @@ -0,0 +1,33 @@ +""" +Утилиты для генерации случайных строк. + +Используются генераторами фиктивных значений для создания +случайных цифр и букв в номерах/реквизитах. +""" + +import random +import string + + +def random_digits(n: int) -> str: + """Сгенерировать строку из n случайных цифр. + + Args: + n: Количество цифр + + Returns: + Строка из n случайных цифр (0-9) + """ + return ''.join(random.choice(string.digits) for _ in range(n)) + + +def random_letters(n: int) -> str: + """Сгенерировать строку из n случайных строчных латинских букв. + + Args: + n: Количество букв + + Returns: + Строка из n случайных букв (a-z) + """ + return ''.join(random.choice(string.ascii_lowercase) for _ in range(n))