generators: fallback.py — character-class preserving для неизвестных типов
Deploy drhider / validate (push) Waiting to run

This commit is contained in:
2026-07-12 09:09:54 +04:00
parent d607d7d306
commit 579f9c8334
5 changed files with 273 additions and 0 deletions
+4
View File
@@ -13,6 +13,7 @@ from .kpp import generate_kpp
from .bik import generate_bik
from .accounts import generate_rs, generate_ks
from .passport import generate_passport
from .fallback import generate_fallback
# ═══════════════════════════════════════════════════════════════════════════
# Маппинг: entity_type → функция-генератор
@@ -31,3 +32,6 @@ ENTITY_GENERATORS = {
"ks": generate_ks, # корреспондентский счёт
"passport": generate_passport,
}
# Fallback-генератор — экспортируется отдельно для использования в scanner/obfuscator
FALLBACK_GENERATOR = generate_fallback
+64
View File
@@ -0,0 +1,64 @@
"""
Fallback-генератор фиктивных значений для неизвестных типов сущностей.
Используется когда LLM находит сущность с типом, которого нет
в специализированных генераторах (например, "contract_number", "employee_id").
Принцип: character-class preserving замена.
- Цифры → случайные цифры
- Буквы → случайные буквы (того же алфавита)
- Пробелы/знаки препинания → сохраняются
- Длина строки сохраняется
"""
import random
import string
def generate_fallback(original: str) -> str:
"""Сгенерировать фиктивное значение, сохраняя структуру оригинала.
Правила замены:
- [0-9] → случайная цифра
- [A-Za-z] → случайная буква того же регистра
- [А-Яа-я] → случайная кириллическая буква того же регистра
- Все остальные символы (пробелы, дефисы, спецсимволы) → без изменений
Args:
original: Оригинальное значение сущности
Returns:
Фиктивное значение той же длины и структуры
Example:
"Договор №123/2024""Фтщшлпь №847/5921"
"EMP-0042""XQJ-8193"
"""
result = []
for ch in original:
if ch.isdigit():
# Цифра → случайная цифра
result.append(random.choice(string.digits))
elif 'A' <= ch <= 'Z':
# Заглавная латиница → случайная заглавная латиница
result.append(random.choice(string.ascii_uppercase))
elif 'a' <= ch <= 'z':
# Строчная латиница → случайная строчная латиница
result.append(random.choice(string.ascii_lowercase))
elif 'А' <= ch <= 'Я':
# Заглавная кириллица → случайная заглавная кириллица
result.append(chr(random.randint(0x0410, 0x042F)))
elif 'а' <= ch <= 'я' or ch == 'ё':
# Строчная кириллица → случайная строчная кириллица
result.append(chr(random.randint(0x0430, 0x044F)))
else:
# Всё остальное (пробелы, дефисы, слэши, точки) → сохранить
result.append(ch)
return ''.join(result)