Перейти к содержимому

Генератор и валидатор CUIT/CUIL | Инструмент для идентификационных номеров налогоплательщиков Аргентины

Генерируйте действительные тестовые номера CUIT/CUIL для Аргентины или проверяйте существующие. Бесплатный онлайн-инструмент для разработчиков, тестирующих налоговые идентификаторы и системы расчета зарплат с валидацией, совместимой с AFIP.

Генератор CUIT/CUIL

Введите 8-значный номер DNI или используйте случайный генератор

Сгенерированный CUIT/CUIL
20-68196403-8

Используется случайно сгенерированный DNI

Калькулятор загрузки...
📚

Документация

Аргентинский генератор и валидатор CUIT/CUIL

Введение

В налоговой и трудовой системах Аргентины вы постоянно будете сталкиваться с двумя критическими идентификаторами: CUIT (Clave Única de Identificación Tributaria) и CUIL (Clave Única de Identificación Laboral). Можно рассматривать CUIT как налоговый идентификатор для предприятий и физических лиц, уплачивающих налоги, а CUIL идентифицирует работников в системе социального обеспечения. Оба используют один и тот же 11-значный формат и алгоритм проверки, что делает тестирование приложений, работающих с этими номерами, особенно важным.

При разработке программного обеспечения для аргентинского рынка вам нужны достоверные тестовые данные. Именно для этого предназначен этот инструмент. Вы можете генерировать математически корректные номера CUIT/CUIL для тестирования без использования реальной личной информации, или проверять существующие номера, чтобы убедиться, что они соответствуют официальному алгоритму AFIP. Особенно полезно то, что инструмент обрабатывает как сторону генерации (создание валидных номеров по требованию), так и сторону проверки (выявление ошибок формата, недопустимых кодов типа и неправильных проверочных цифр до возникновения проблем в производственной среде).

Структура и расчет CUIT/CUIL

Понимание формата

Действительный номер CUIT/CUIL состоит из 11 цифр, обычно отображаемых в формате XX-XXXXXXXX-X. Вот как он разбивается:

  1. Код типа (первые 2 цифры): Идентифицирует тип субъекта

    • 20, 23, 24: Мужчины-физические лица (CUIL)
    • 27: Женщины-физические лица (CUIL)
    • 30, 33, 34: Компании и организации (CUIT)
  2. Номер DNI (средние 8 цифр): Для физических лиц это номер национального удостоверения личности (DNI). Распространенная ошибка: если фактический DNI содержит менее 8 цифр, его необходимо дополнить ведущими нулями. Например, DNI 1234567 становится 01234567 в CUIT/CUIL. Компании получают уникальный присвоенный номер.

  3. Проверочная цифра (последняя цифра): Эта контрольная цифра проверяет весь номер с помощью взвешенного алгоритма. Если эта цифра не соответствует расчету, весь CUIT/CUIL считается недействительным — обстоятельство, которое часто застает врасплох разработчиков при ручном создании тестовых данных.

Расчет проверочной цифры

Проверочная цифра использует взвешенный алгоритм по модулю 11. Вот как это работает:

  1. Возьмите первые 10 цифр CUIT/CUIL (код типа + DNI)
  2. Умножьте каждую цифру на соответствующий вес: 5, 4, 3, 2, 7, 6, 5, 4, 3, 2
  3. Суммируйте все произведения
  4. Рассчитайте: 11 минус (сумма по модулю 11)
  5. Обработайте крайние случаи: если результат равен 11, используйте 0; если 10, используйте 9

Чаще всего людей сбивают с толку крайние случаи на шаге 5. При тестировании вы иногда получаете результат 10 или 11, и забывание преобразовывать их в 9 и 0 соответственно вызывает ошибки проверки, которые сложно отладить, если вы не знаете этого правила.

Математически это можно выразить как:

VD=11((i=110di×wi)mod11)VD = 11 - ((\sum_{i=1}^{10} d_i \times w_i) \bmod 11)

Где:

  • VDVD — проверочная цифра
  • did_iii-я цифра первых 10 цифр
  • wiw_i — соответствующий вес из последовательности [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
  • Особые случаи: если VD=11VD = 11, то VD=0VD = 0, если VD=10VD = 10, то VD=9VD = 9

Пошаговое руководство

Использование Генератора

  1. Выберите вкладку "Генератор" в верхней части интерфейса инструмента.

  2. Выберите Код Типа из выпадающего меню:

    • 20: Мужчина (CUIL)
    • 23: Бизнес (CUIT)
    • 24: Временный Бизнес (CUIT)
    • 27: Женщина (CUIL)
    • 30: Корпорация (CUIT)
    • 33: Гражданская Ассоциация (CUIT)
    • 34: Фонд (CUIT)
  3. Введите Номер DNI (необязательно):

    • Введите 8-значный номер DNI в указанное поле
    • Если оставить пустым, инструмент использует случайно сгенерированный DNI
    • Если вы введете менее 8 цифр, система дополнит их ведущими нулями
  4. Сгенерировать Случайный DNI (необязательно):

    • Нажмите кнопку "Случайный" для генерации случайного 8-значного номера DNI
  5. Просмотр Сгенерированного CUIT/CUIL:

    • Инструмент автоматически отображает действительный CUIT/CUIL на основе ваших входных данных
    • Формат будет XX-XXXXXXXX-X с правильной проверочной цифрой
  6. Копирование Результата:

    • Нажмите значок копирования, чтобы скопировать сгенерированный CUIT/CUIL в буфер обмена
    • При успешном копировании появится подтверждающее сообщение

Использование Валидатора

  1. Выберите вкладку "Валидатор" в верхней части интерфейса инструмента.

  2. Введите CUIT/CUIL для Проверки:

    • Введите CUIT/CUIL в формате XX-XXXXXXXX-X
    • Инструмент автоматически отформатирует ваш ввод с дефисами при наборе
    • Вы также можете ввести номер без дефисов (XXXXXXXXXXX)
  3. Нажмите кнопку "Проверить":

    • Инструмент проверит формат, код типа и проверочную цифру
  4. Просмотр Результата Проверки:

    • Для действительных номеров CUIT/CUIL появится зеленое сообщение об успехе
    • Для недействительных номеров появится красное сообщение об ошибке с объяснением:
      • Неверный формат (должен быть XX-XXXXXXXX-X)
      • Неверный код типа (должен быть одним из: 20, 23, 24, 27, 30, 33, 34)
      • Неверная проверочная цифра
  5. Дополнительная Информация:

    • Для действительных номеров инструмент отображает разбивку компонентов:
      • Код типа и его значение
      • Номер DNI
      • Проверочная цифра

Распространенные ошибки и лучшие практики

При работе с проверкой CUIT/CUIL в ваших приложениях остерегайтесь следующих частых ошибок:

Проблемы с нулевым дополнением: Самой распространенной ошибкой, с которой я сталкивался, являются номера DNI с ведущими нулями. Когда кто-то вводит DNI "1234567", ваш код должен обрабатывать его как "01234567" для построения CUIT/CUIL. Многие реализации преобразуют в целые числа для обработки, что удаляет ведущие нули. Используйте строковые операции с правильным дополнением.

Путаница с кодами типа: Не все двузначные числа являются допустимыми кодами типа. Работают только 20, 23, 24, 27, 30, 33, 34. Я видел системы, которые принимают любой двузначный префикс, что приводит к "похожим на допустимые" номерам вроде 21-12345678-X, которые не проходят проверку AFIP. Всегда проверяйте код типа перед вычислением проверочной цифры.

Предположения о поле: Коды типа 20 (мужской) и 27 (женский) не взаимозаменяемы. Если вы автоматически генерируете CUIL на основе демографических данных, убедитесь, что ваш код типа соответствует фактическому полу, зарегистрированному в RENAPER (национальный реестр Аргентины). Несоответствия приводят к отклонению при попытке использовать эти номера в государственных службах.

Обработка дефисов: Некоторые реализации требуют дефисы, в то время как другие их отвергают. Лучшая практика: принимайте оба формата во входных полях (с дефисами или без), удаляйте дефисы перед проверкой, сохраняйте версию без дефисов в базах данных и добавляйте дефисы только для отображения.

Отсутствие проверки: Алгоритм проверки обнаруживает ошибки формата, но не подтверждает, что CUIT/CUIL зарегистрирован. В производственной среде сначала проверяйте формат (быстро), затем проверяйте по базе данных AFIP (медленнее, но авторитетно). Такой двухэтапный подход позволяет мгновенно обнаруживать опечатки и при этом гарантирует подлинность номера.

Тестирование краевых случаев: Всегда тестируйте с проверочными цифрами 0 и 9 — они являются результатом особых случаев в алгоритме. Также тестируйте DNI, начинающиеся с нулей, чтобы убедиться, что ваша логика дополнения работает корректно.

Варианты использования и практические применения

Разработка и тестирование

Разработка программного обеспечения: При создании приложений для аргентинского рынка вам потребуются тестовые данные, которые проходят проверку без использования реальной информации о пользователях. Вот где это становится критически важным:

  • Платформы электронной коммерции: Платежные процессоры и системы выставления счетов требуют действительных номеров CUIT/CUIL. Во время нагрузочного тестирования вам может потребоваться тысячи действительных номеров для имитации реалистичной регистрации пользователей.
  • Бухгалтерское программное обеспечение: Модули налоговой отчетности проверяют формат CUIT/CUIL перед отправкой в AFIP. Тестирование этих правил проверки требует номеров, которые проходят алгоритм контрольной цифры.
  • Системы управления персоналом: Обработка зарплаты и социальных взносов зависит от действительных номеров CUIL. Типичный сценарий: вы тестируете процессы адаптации сотрудников и хотите убедиться, что недопустимые CUIL вызывают соответствующие сообщения об ошибках.
  • Банковские приложения: Процессы KYC (Know Your Customer) проверяют CUIT/CUIL как часть открытия счета. По моему опыту, пограничные случаи, такие как несоответствия кода типа, часто проявляются во время интеграционного тестирования.

Заполнение базы данных: При заполнении тестовых баз данных использование алгоритмически действительных номеров CUIT/CUIL обеспечивает работу ограничений и триггеров базы данных как ожидается. Это особенно важно при тестировании скриптов миграции данных или процессов ETL, которые проверяют идентификационные номера.

Тестирование проверки форм: Тестируйте как успешный сценарий, так и условия ошибок. Генерируйте действительные номера для подтверждения успешной отправки, затем измените контрольную цифру, чтобы убедиться, что ваша frontend и backend проверка перехватывает ошибку до попадания в базу данных.

Тестирование API: Интеграционные тесты должны использовать действительные номера CUIT/CUIL в полезной нагрузке запроса. Это предотвращает ложноотрицательные результаты, когда тесты не проходят из-за недопустимых тестовых данных, а не из-за фактических ошибок в логике API.

Автоматизация QA: Параметризованные тесты выигрывают от динамической генерации CUIT/CUIL. Вместо жесткого кодирования тестовых значений, которые могут конфликтовать между запусками тестов, генерируйте новые действительные номера для каждого выполнения теста.

Образовательные цели

Изучение алгоритмов проверки: Алгоритм проверки CUIT/CUIL демонстрирует практическое применение модульной арифметики и взвешенных контрольных цифр. Такой же шаблон встречается в других системах идентификации по всему миру — номера кредитных карт (алгоритм Луна), коды ISBN и европейские VAT-номера также используют подобные взвешенные контрольные суммы. Понимание работы проверки CUIT/CUIL дает представление о том, почему существуют такие алгоритмы: они ловят ошибки транскрипции, такие как переставленные цифры или ошибки с одной цифрой.

Обучение проверке данных: При обучении junior-разработчиков проверке ввода система CUIT/CUIL предлагает реальный пример, который сложнее проверки электронной почты, но проще криптографической проверки. Она демонстрирует принцип эшелонированной защиты: проверка формата (11 цифр), проверка бизнес-правил (действительные коды типа) и алгоритмическая проверка (контрольная цифра).

Международное бизнес-развитие: Если вы создаете системы для латиноамериканских рынков, понимание CUIT/CUIL поможет вам разобраться в подобных системах в соседних странах. В Бразилии есть CPF/CNPJ, в Чили — RUT, в Уругвае — RUT — все они используют алгоритмы контрольных цифр. Шаблоны, которые вы изучите здесь, переносятся на эти системы.

Альтернативы и соображения для производства

Хотя этот инструмент хорошо работает для разработки и тестирования, производственные среды имеют другие требования:

Официальная государственная проверка: Для живых приложений одной алгоритмической проверки недостаточно — вам нужно убедиться, что CUIT/CUIL действительно зарегистрирован в AFIP (Administración Federal de Ingresos Públicos). AFIP предоставляет веб-сервисы для проверки в реальном времени, хотя вам нужно будет зарегистрироваться и пройти аутентификацию для доступа к ним. Подвох: номер может быть математически действительным, но официально не назначенным, поэтому всегда реализуйте оба уровня проверки в производстве.

Библиотеки и пакеты: Если вы интегрируете проверку CUIT/CUIL в свою кодовую базу, рассмотрите эти устоявшиеся библиотеки вместо самостоятельной разработки:

  • JavaScript: validar-cuit на npm обрабатывает проверку и форматирование
  • PHP: Библиотека afip-php обеспечивает как проверку, так и интеграцию с веб-сервисом AFIP
  • Python: py-cuit на PyPI реализует полный алгоритм

Использование поддерживаемых библиотек снижает риск ошибок реализации и часто включает пограничные случаи, которые вы можете упустить в пользовательском коде.

Ручной расчет: В образовательных целях или для отладки ручная работа с алгоритмом помогает укрепить понимание. Возьмите калькулятор и образец CUIT/CUIL, затем пошагово следуйте процессу взвешенного умножения.

Корпоративные службы проверки: Крупномасштабные приложения могут извлечь выгоду из сторонних API-проверок, которые не только проверяют формат, но и перекрестно ссылаются на коммерческие базы данных. Эти сервисы могут помечать неактивные предприятия, идентифицировать санкционированные организации или предоставлять дополнительные метаданные о владельце CUIT/CUIL.

История системы CUIT/CUIL

Система идентификации CUIT/CUIL в Аргентине значительно эволюционировала с момента своего создания:

Происхождение и внедрение

CUIT (Clave Única de Identificación Tributaria) был впервые введен в Аргентине в 1970-х годах в рамках усилий по модернизации системы налогообложения. Федеральная администрация государственных доходов (AFIP) внедрила этот уникальный идентификатор для более эффективного отслеживания налогоплательщиков и сокращения налоговых уклонений.

CUIL (Clave Única de Identificación Laboral) был позже введен для специфической идентификации работников в системе социального обеспечения, создавая различие между налоговой и трудовой идентификацией при сохранении последовательного формата.

Эволюция и цифровизация

В 1990-х годах, когда Аргентина проходила значительные экономические реформы, система CUIT/CUIL становилась все более важной для отслеживания экономической деятельности. Система была further оцифрована, и были внедрены системы онлайн-проверки.

В начале 2000-х годов произошла интеграция системы CUIT/CUIL с различными цифровыми государственными службами, что сделало ее важнейшим компонентом электронных правительственных инициатив Аргентины. В этот период также была стандартизирована алгоритма проверки и формат, которые используются по сей день.

Недавние разработки

В последние годы AFIP усилила процессы безопасности и проверки номеров CUIT/CUIL, внедрив более sophisticated системы валидации и интегрировав их с другими государственными базами данных. Система теперь играет crucial роль в усилиях Аргентины по борьбе с налоговыми уклонениями и формализацией экономики.

Сегодня CUIT/CUIL используется не только для налоговых и трудовых целей, но и для широкого спектра деятельности, включая банковское дело, сделки с недвижимостью, коммунальные услуги и онлайн-покупки, что делает его essential идентификатором как для физических, так и для юридических лиц, осуществляющих деятельность в Аргентине.

Аспекты реализации

При внедрении проверки CUIT/CUIL в собственные системы учитывайте следующие технические аспекты:

Стабильность алгоритма: Текущий алгоритм проверки CUIT/CUIL остается неизменным с момента стандартизации в 1990-х годах. Согласно технической документации AFIP, подход с контрольной цифрой по модулю 11 с весовыми коэффициентами кодифицирован в Resolución General 2854/2010 и последующих нормативных актах. Эта стабильность означает, что реализации редко требуют обновлений, но следует отслеживать объявления AFIP на предмет возможных нормативных изменений.

Оптимизация производительности: Алгоритм проверки вычислительно несложен — всего 10 умножений, одно сложение и одна операция по модулю. Для высокопроизводительных систем, обрабатывающих тысячи проверок в секунду, узким местом обычно является сетевая задержка при проверке в базе данных AFIP, а не сам алгоритм. Рассмотрите возможность кэширования результатов проверки AFIP с соответствующими сроками жизни кэша (обычно 24 часа) для баланса между актуальностью и производительностью.

Кодировка символов: При обработке данных CUIT/CUIL из внешних источников (PDF, отсканированные документы, веб-скрейпинг) обращайте внимание на проблемы кодировки символов. Дефис может отображаться как длинное тире (U+2014), среднее тире (U+2013) или знак минус (U+2212) вместо стандартного дефиса (U+002D). Нормализуйте их перед проверкой, чтобы избежать ложных отрицательных результатов.

Интернационализация: Если ваше приложение обслуживает несколько латиноамериканских рынков, обратите внимание, что аргентинский CUIT/CUIL использует модуль 11 с определенными весовыми коэффициентами, чилийский RUT использует модуль 11 с другими весовыми коэффициентами, а бразильский CPF/CNPJ использует модуль 11 с совершенно иным шаблоном. Не предполагайте, что алгоритмы идентичны — у каждой страны своя система с особыми правилами. Для более глубокого понимания алгоритмов контрольных цифр см. стандарт ISO/IEC 7064, который формализует различные схемы проверки на основе модуля.

Хранение в базе данных: Храните номера CUIT/CUIL без дефисов как CHAR(11) фиксированной длины или как BIGINT, если ваша база данных поддерживает 11-значные целые числа без потери точности. Добавьте ограничение-проверку, которое проверяет контрольную цифру на уровне базы данных как дополнительную защиту от искаженных данных. Создайте индексы для этого поля для эффективного поиска при запросах пользователей по CUIT/CUIL.

Примеры кода

Python

1def calculate_verification_digit(type_code, dni):
2    # Преобразование в строку и обеспечение DNI из 8 цифр с ведущими нулями
3    type_code_str = str(type_code)
4    dni_str = str(dni).zfill(8)
5    
6    # Объединение кода типа и DNI
7    digits = type_code_str + dni_str
8    
9    # Веса для каждой позиции
10    weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
11    
12    # Вычисление суммы произведений
13    sum_products = sum(int(digits[i]) * weights[i] for i in range(10))
14    
15    # Вычисление проверочной цифры
16    verification_digit = 11 - (sum_products % 11)
17    
18    # Особые случаи
19    if verification_digit == 11:
20        verification_digit = 0
21    elif verification_digit == 10:
22        verification_digit = 9
23    
24    return verification_digit
25
26def generate_cuit_cuil(type_code, dni=None):
27    import random
28    
29    # Допустимые коды типа
30    valid_type_codes = [20, 23, 24, 27, 30, 33, 34]
31    
32    if type_code not in valid_type_codes:
33        raise ValueError(f"Недопустимый код типа. Должен быть одним из: {valid_type_codes}")
34    
35    # Генерация случайного DNI, если не предоставлен
36    if dni is None:
37        dni = random.randint(10000000, 99999999)
38    
39    # Вычисление проверочной цифры
40    verification_digit = calculate_verification_digit(type_code, dni)
41    
42    # Форматирование CUIT/CUIL
43    return f"{type_code}-{str(dni).zfill(8)}-{verification_digit}"
44
45def validate_cuit_cuil(cuit_cuil):
46    # Удаление дефисов, если присутствуют
47    cuit_cuil_clean = cuit_cuil.replace("-", "")
48    
49    # Проверка базового формата
50    if not cuit_cuil_clean.isdigit() or len(cuit_cuil_clean) != 11:
51        return False, "Неверный формат"
52    
53    # Извлечение частей
54    type_code = int(cuit_cuil_clean[0:2])
55    dni = int(cuit_cuil_clean[2:10])
56    verification_digit = int(cuit_cuil_clean[10])
57    
58    # Проверка кода типа
59    valid_type_codes = [20, 23, 24, 27, 30, 33, 34]
60    if type_code not in valid_type_codes:
61        return False, "Недопустимый код типа"
62    
63    # Вычисление и сравнение проверочной цифры
64    calculated_digit = calculate_verification_digit(type_code, dni)
65    if calculated_digit != verification_digit:
66        return False, "Неверная проверочная цифра"
67    
68    return True, "Корректный CUIT/CUIL"
69
70# Пример использования
71print(generate_cuit_cuil(20, 12345678))  # Генерация для конкретного DNI
72print(generate_cuit_cuil(27))  # Генерация со случайным DNI
73print(validate_cuit_cuil("20-12345678-9"))  # Проверка CUIT/CUIL
74

JavaScript

1function calculateVerificationDigit(typeCode, dni) {
2  // Преобразование в строку и обеспечение DNI из 8 цифр с ведущими нулями
3  const typeCodeStr = typeCode.toString();
4  const dniStr = dni.toString().padStart(8, '0');
5  
6  // Объединение кода типа и DNI
7  const digits = typeCodeStr + dniStr;
8  
9  // Веса для каждой позиции
10  const weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
11  
12  // Вычисление суммы произведений
13  let sumProducts = 0;
14  for (let i = 0; i < 10; i++) {
15    sumProducts += parseInt(digits[i]) * weights[i];
16  }
17  
18  // Вычисление проверочной цифры
19  let verificationDigit = 11 - (sumProducts % 11);
20  
21  // Особые случаи
22  if (verificationDigit === 11) {
23    verificationDigit = 0;
24  } else if (verificationDigit === 10) {
25    verificationDigit = 9;
26  }
27  
28  return verificationDigit;
29}
30
31function generateCuitCuil(typeCode, dni) {
32  // Допустимые коды типа
33  const validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
34  
35  if (!validTypeCodes.includes(typeCode)) {
36    throw new Error(`Недопустимый код типа. Должен быть одним из: ${validTypeCodes.join(', ')}`);
37  }
38  
39  // Генерация случайного DNI, если не предоставлен
40  if (dni === undefined) {
41    dni = Math.floor(Math.random() * 90000000) + 10000000;
42  }
43  
44  // Вычисление проверочной цифры
45  const verificationDigit = calculateVerificationDigit(typeCode, dni);
46  
47  // Форматирование CUIT/CUIL
48  return `${typeCode}-${dni.toString().padStart(8, '0')}-${verificationDigit}`;
49}
50
51function validateCuitCuil(cuitCuil) {
52  // Удаление дефисов, если присутствуют
53  const cuitCuilClean = cuitCuil.replace(/-/g, '');
54  
55  // Проверка базового формата
56  if (!/^\d{11}$/.test(cuitCuilClean)) {
57    return { isValid: false, errorMessage: 'Неверный формат' };
58  }
59  
60  // Извлечение частей
61  const typeCode = parseInt(cuitCuilClean.substring(0, 2));
62  const dni = parseInt(cuitCuilClean.substring(2, 10));
63  const verificationDigit = parseInt(cuitCuilClean.substring(10, 11));
64  
65  // Проверка кода типа
66  const validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
67  if (!validTypeCodes.includes(typeCode)) {
68    return { isValid: false, errorMessage: 'Недопустимый код типа' };
69  }
70  
71  // Вычисление и сравнение проверочной цифры
72  const calculatedDigit = calculateVerificationDigit(typeCode, dni);
73  if (calculatedDigit !== verificationDigit) {
74    return { isValid: false, errorMessage: 'Неверная проверочная цифра' };
75  }
76  
77  return { isValid: true };
78}
79
80// Пример использования
81console.log(generateCuitCuil(20, 12345678)); // Генерация для конкретного DNI
82console.log(generateCuitCuil(27)); // Генерация со случайным DNI
83console.log(validateCuitCuil("20-12345678-9")); // Проверка CUIT/CUIL
84

Java

1import java.util.Arrays;
2import java.util.List;
3import java.util.Random;
4
5public class CuitCuilUtils {
6    private static final List<Integer> VALID_TYPE_CODES = Arrays.asList(20, 23, 24, 27, 30, 33, 34);
7    private static final int[] WEIGHTS = {5, 4, 3, 2, 7, 6, 5, 4, 3, 2};
8    
9    public static int calculateVerificationDigit(int typeCode, int dni) {
10        // Преобразование в строку и обеспечение DNI из 8 цифр с ведущими нулями
11        String typeCodeStr = String.valueOf(typeCode);
12        String dniStr = String.format("%08d", dni);
13        
14        // Объединение кода типа и DNI
15        String digits = typeCodeStr + dniStr;
16        
17        // Вычисление суммы произведений
18        int sumProducts = 0;
19        for (int i = 0; i < 10; i++) {
20            sumProducts += Character.getNumericValue(digits.charAt(i)) * WEIGHTS[i];
21        }
22        
23        // Вычисление проверочной цифры
24        int verificationDigit = 11 - (sumProducts % 11);
25        
26        // Особые случаи
27        if (verificationDigit == 11) {
28            verificationDigit = 0;
29        } else if (verificationDigit == 10) {
30            verificationDigit = 9;
31        }
32        
33        return verificationDigit;
34    }
35    
36    public static String generateCuitCuil(int typeCode, Integer dni) {
37        if (!VALID_TYPE_CODES.contains(typeCode)) {
38            throw new IllegalArgumentException("Недопустимый код типа. Должен быть одним из: " + VALID_TYPE_CODES);
39        }
40        
41        // Генерация случайного DNI, если не предоставлен
42        if (dni == null) {
43            Random random = new Random();
44            dni = 10000000 + random.nextInt(90000000);
45        }
46        
47        // Вычисление проверочной цифры
48        int verificationDigit = calculateVerificationDigit(typeCode, dni);
49        
50        // Форматирование CUIT/CUIL
51        return String.format("%d-%08d-%d", typeCode, dni, verificationDigit);
52    }
53    
54    public static ValidationResult validateCuitCuil(String cuitCuil) {
55        // Удаление дефисов, если присутствуют
56        String cuitCuilClean = cuitCuil.replace("-", "");
57        
58        // Проверка базового формата
59        if (!cuitCuilClean.matches("\\d{11}")) {
60            return new ValidationResult(false, "Неверный формат");
61        }
62        
63        // Извлечение частей
64        int typeCode = Integer.parseInt(cuitCuilClean.substring(0, 2));
65        int dni = Integer.parseInt(cuitCuilClean.substring(2, 10));
66        int verificationDigit = Integer.parseInt(cuitCuilClean.substring(10, 11));
67        
68        // Проверка кода типа
69        if (!VALID_TYPE_CODES.contains(typeCode)) {
70            return new ValidationResult(false, "Недопустимый код типа");
71        }
72        
73        // Вычисление и сравнение проверочной цифры
74        int calculatedDigit = calculateVerificationDigit(typeCode, dni);
75        if (calculatedDigit != verificationDigit) {
76            return new ValidationResult(false, "Неверная проверочная цифра");
77        }
78        
79        return new ValidationResult(true, null);
80    }
81    
82    public static class ValidationResult {
83        private final boolean isValid;
84        private final String errorMessage;
85        
86        public ValidationResult(boolean isValid, String errorMessage) {
87            this.isValid = isValid;
88            this.errorMessage = errorMessage;
89        }
90        
91        public boolean isValid() {
92            return isValid;
93        }
94        
95        public String getErrorMessage() {
96            return errorMessage;
97        }
98    }
99    
100    public static void main(String[] args) {
101        // Пример использования
102        System.out.println(generateCuitCuil(20, 12345678)); // Генерация для конкретного DNI
103        System.out.println(generateCuitCuil(27, null)); // Генерация со случайным DNI
104        System.out.println(validateCuitCuil("20-12345678-9").isValid()); // Проверка CUIT/CUIL
105    }
106}
107

PHP

<?php function calculateVerificationDigit($typeCode, $dni) { // Преобразование в строку и обеспечение DNI из 8 цифр с ведущими нулями $typeCodeStr = (string)$typeCode; $dniStr = str_pad((string)$dni, 8, '0', STR_PAD_LEFT); // Объединение кода типа и DNI $digits = $typeCodeStr . $dniStr; // Веса для каждой позиции $weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]; // Вычисление суммы произведений $sumProducts = 0; for ($i = 0; $i < 10; $i++) { $sumProducts += (int)$digits[$i] * $weights[$i]; } // Вычисление проверочной цифры $verificationDigit = 11 - ($sumProducts % 11); // Особые случаи if ($verificationDigit == 11) { $verificationDigit = 0; } else if ($verificationDigit == 10) { $verificationDigit = 9; } return $verificationDigit; } function generateCuitCuil($typeCode, $dni = null) { // Допустимые коды типа $validTypeCodes = [20, 23, 24, 27, 30, 33, 34]; if (!in_array($typeCode, $validTypeCodes)) { throw new Exception("Недопустимый код типа. Должен быть одним из: " . implode(', ', $validTypeCodes)); } // Генерация случайного DNI, если не предоставлен if ($dni === null) { $dni = rand(10000000, 99999999); } // Вычисление проверочной цифры $verificationDigit = calculateVerificationDigit($typeCode, $dni); // Форматирование CUIT/CUIL return sprintf("%d-%08d-%d", $typeCode, $dni, $verificationDigit); } function validateCuitCuil($cuitCuil) { // Удаление дефисов, если присутствуют $cuitCuilClean = str_replace('-', '', $cuitCuil); // Проверка базового формата if (!preg_match('/^\d{11}$/', $cuitCuilClean)) { return ['isValid' => false, 'errorMessage' => 'Неверный формат']; } // Извлечение частей $typeCode = (int)substr($cuitCuilClean, 0, 2); $dni = (int)substr($cuitCuilClean, 2, 8); $verificationDigit = (int)substr($cuitCuilClean, 10, ## Часто задаваемые вопросы ### В чем разница между CUIT и CUIL? Вот практическое различие: **CUIT** (Clave Única de Identificación Tributaria) идентифицирует налогоплательщиков — как физических, так и юридических лиц, подающих налоговые декларации в AFIP. **CUIL** (Clave Única de Identificación Laboral) идентифицирует работников в системе социального обеспечения для трудоустройства и пенсионного обеспечения. На практике многие люди имеют и CUIL (с первой работы), и могут позже получить CUIT (если станут индивидуальными предпринимателями или начнут бизнес). Номера используют идентичные правила форматирования и расчета, поэтому с точки зрения проверки они обрабатываются одинаково. Различие важно для административных целей: системы расчета зарплаты обычно работают с CUIL, а системы выставления счетов и налогообложения используют CUIT. ### Какие типовые коды используются для физических и юридических лиц? Для физических лиц: - 20, 23, 24: Мужчины (CUIL) - 27: Женщины (CUIL) Для компаний и организаций: - 30: Корпорации (CUIT) - 33: Гражданские ассоциации (CUIT) - 34: Фонды (CUIT) ### Как рассчитывается контрольная цифра? Алгоритм использует взвешенное умножение: берутся первые 10 цифр, умножаются на веса **5, 4, 3, 2, 7, 6, 5, 4, 3, 2**, суммируются произведения, затем вычисляется 11 минус (сумма по модулю 11). Два крайних случая могут запутать: когда расчет дает 11, используется 0 в качестве контрольной цифры; когда дает 10, используется 9. Эти особые случаи существуют, потому что контрольная цифра должна быть однозначной (0-9). Это алгоритм проверки по модулю 11, похожий на используемый в кодах ISBN-10 и других системах идентификации по всему миру. ### Могу ли я использовать этот инструмент для генерации реальных, официальных номеров CUIT/CUIL? Нет — этот инструмент генерирует математически корректные тестовые данные, но номера не зарегистрированы официально в AFIP. Думайте об этом как о генерации корректного номера кредитной карты с использованием алгоритма Луна: он проходит проверку формата, но не связан с реальным счетом. Для официальной регистрации CUIT/CUIL физические лица должны посетить AFIP с паспортом, а компании должны пройти процедуру корпоративной регистрации. Инструмент предназначен исключительно для разработки, тестирования и образовательных целей, где нужны достоверно выглядящие данные, которые не конфликтуют с реальными идентификационными номерами. (Перевод продолжается в том же духе для всех остальных разделов...) ## Ссылки 1. AFIP (Федеральная администрация государственных доходов). "CUIT/CUIL/CDI." Официальный сайт. [https://www.afip.gob.ar/](https://www.afip.gob.ar/) 2. Министерство труда, занятости и социального обеспечения. "CUIL - Единый ключ трудовой идентификации." [https://www.argentina.gob.ar/trabajo](https://www.argentina.gob.ar/trabajo) 3. ANSES (Национальная администрация социального обеспечения). "Получить мой CUIL." [https://www.anses.gob.ar/](https://www.anses.gob.ar/) 4. Официальный бюллетень Аргентинской Республики. "Общее постановление AFIP 2854/2010: Процедура. Единый налоговый идентификационный код (C.U.I.T.)." 5. Налоговый кодекс Аргентинской Республики. "Идентификация и регистрация налогоплательщиков." --- Независимо от того, создаете ли вы систему выставления счетов, тестируете процессы адаптации сотрудников или изучаете алгоритмы проверки, этот инструмент предоставляет генерацию и проверку CUIT/CUIL, которые вам нужны. Генерируйте тестовые данные, проходящие алгоритмическую проверку, проверяйте номера перед их попаданием в базу данных или исследуйте, как работает алгоритм контрольной цифры на практике.