Andrey Epifancev 801d9948ca synthgen: каркас, настройки, копии модулей #35 (#38)
- synthgen/config.py: Config, load_config (YAML + --set), dump_config, проверки диапазонов §3
- synthgen/rng.py: rng_for (SHA-256 → Random), stable_hash
- synthgen/__main__.py: разбор --config/--set/--out/--force, ошибка конфигурации → код 2
- synthgen/examples/default.yaml: все ключи §3 со значениями по умолчанию
- копии из synthetic-group/gen (#35): inn, xlsx, ledger, chart (+80.09, 91.09 из seed arm-core)
- тесты: config, inn, ledger; conftest с маркерами parser/slow
- .gitignore: out/
- спека: решения 15–16

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-11-12 23:35:17 +04:00

37 lines
1.3 KiB
Python

"""Источник: synthetic-group/gen/inn.py (#35).
Вымышленные ИНН: регион `00` (не существует), верная контрольная сумма ФНС. Без случайности."""
_W10 = (2, 4, 10, 3, 5, 9, 4, 6, 8)
_W12_1 = (7, 2, 4, 10, 3, 5, 9, 4, 6, 8)
_W12_2 = (3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8)
def _check(digits: list[int], weights: tuple[int, ...]) -> int:
return sum(d * w for d, w in zip(digits, weights)) % 11 % 10
def make_inn10(seq: int) -> str:
"""ИНН юрлица: `00` + 7 цифр номера + контрольная цифра."""
body = [int(c) for c in f"00{seq:07d}"]
return "".join(map(str, body)) + str(_check(body, _W10))
def make_inn12(seq: int) -> str:
"""ИНН физлица/ИП: `00` + 8 цифр номера + две контрольные цифры."""
body = [int(c) for c in f"00{seq:08d}"]
body.append(_check(body, _W12_1))
body.append(_check(body, _W12_2))
return "".join(map(str, body))
def is_valid(inn: str) -> bool:
if not inn.isdigit():
return False
digits = [int(c) for c in inn]
if len(digits) == 10:
return digits[9] == _check(digits[:9], _W10)
if len(digits) == 12:
return digits[10] == _check(digits[:10], _W12_1) and digits[11] == _check(digits[:11], _W12_2)
return False