Перейти до вмісту

Генератор і Валідатор CUIT/CUIL | Інструмент для Ідентифікаційних Номерів Аргентини

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

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

Введіть 8-значний номер DNI або використайте випадковий генератор

Згенерований CUIT/CUIL
20-51851457-2

Використання випадково згенерованого 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 та європейські ПДВ-номери також використовують подібні підходи зважених контрольних сум. Розуміння роботи перевірки CUIT/CUIL дає уявлення про те, навіщо існують ці алгоритми: вони виявляють помилки транскрипції, такі як переставлені цифри або помилки в одній цифрі.

Навчання перевірці даних: При навчанні молодших розробників перевірці введення, система 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 стала дедалі важливішою для відстеження економічної діяльності. Система була додатково оцифрована, і було впроваджено онлайн-системи перевірки.

На початку 2000-х років відбулася інтеграція системи CUIT/CUIL з різними цифровими урядовими службами, що зробило її важливим компонентом ініціатив електронного уряду Аргентини. Цей період також ознаменувався стандартизацією алгоритму перевірки та формату, які використовуються й досі.

Останні розробки

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

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

Аспекти впровадження

При впровадженні перевірки CUIT/CUIL у власних системах, розгляньте наступні технічні аспекти:

Стабільність алгоритму: Поточний алгоритм перевірки CUIT/CUIL залишається незмінним з моменту стандартизації у 1990-х роках. Згідно з технічною документацією AFIP, підхід перевірки контрольної цифри за модулем 11 з ваговими коефіцієнтами закріплений у Резолюції General 2854/2010 та подальших нормативних актах. Ця стабільність означає, що реалізації рідко потребують оновлень, але слід стежити за оголошеннями AFIP щодо будь-яких регуляторних змін.

Оптимізація продуктивності: Алгоритм перевірки є обчислювально недорогим — лише 10 множень, одне додавання та одна операція за модулем. Для високопродуктивних систем, що обробляють тисячі перевірок за секунду, вузьким місцем зазвичай є мережева затримка при перевірці бази даних AFIP, а не сам алгоритм. Розгляньте кешування результатів перевірки AFIP з відповідними TTL (зазвичай 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 ## Часто запитувані питання ### У чому різниця між 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 з DNI, а підприємства мають пройти процедуру корпоративної реєстрації. Інструмент призначений виключно для розробки, тестування та освітніх цілей, де потрібні дійсні дані, які не конфліктуватимуть з реальними ідентифікаційними номерами. ### Чому моя перевірка CUIT/CUIL не проходить, хоча формат здається правильним? Коли перевірка не проходить, незважаючи на правильний формат, перевірте ці поширені причини: 1. **Невірний типовий код**: Дійсні лише 20, 23, 24, 27, 30, 33, 34. Використання 21, 25 або інших номерів призведе до помилки. 2. **Невірна перевірочна цифра**: Остання цифра має відповідати обчисленню за алгоритмом. Навіть зміна однієї цифри в частині DNI вимагає перерахунку перевірочної цифри. 3. **Проблеми з форматом**: Має бути точно 11 цифр (XX-XXXXXXXX-X). Стежте за зайвими пробілами або відсутніми провідними нулями. 4. **Приховані символи**: Копіювання з PDF або веб-сайтів інколи додає невидимі символи Юнікоду, що порушують перевірку. Швидка порада для налагодження: видаліть останню цифру та перерахуйте її вручну. Якщо вона не збігається, це і є причина. ### Чи потрібні дефіси в номерах CUIT/CUIL? Дефіси призначені лише для форматування відображення — вони не входять до розрахунку номера. Коли ви бачите **20-12345678-9**, алгоритм турбується лише про 11 цифр: **20123456789**. Більшість реалізацій перевірки видаляють дефіси перед обробкою, тому наш інструмент приймає як **20-12345678-9**, так і **20123456789**. У API та базах даних зазвичай зберігають версію без дефісів і додають їх лише при відображенні користувачам. Цей підхід запобігає збоям перевірки через розбіжності у форматуванні. ### Чи може номер CUIT/CUIL мати менше 8 цифр у частині DNI? Частина DNI завжди має бути точно 8 цифр — без винятків. Якщо в когось DNI має менше цифр (що трапляється зі старими, нижчими номерами), потрібно додавати провідні нулі. Наприклад, DNI **1234567** стає **01234567** у структурі CUIT/CUIL. Це часта причина помилок при перетворенні між форматами DNI та CUIT/CUIL. Я бачив системи, що не проходять перевірку, оскільки забули додати нулі, сприймаючи **1234567** як 7-значне число замість **01234567**. Завжди використовуйте функції додавання нулів у коді замість простого об'єднання рядків. ### Як перевірити, чи зареєстрований CUIT/CUIL офіційно в Аргентині? Наш інструмент перевіряє математичну коректність — формат, типовий код і перевірочну цифру. Але він не може сказати, чи номер дійсно зареєстрований в AFIP або належить реальній особі чи бізнесу. Для офіційної перевірки використовуйте [веб-служби AFIP](https://www.afip.gob.ar/) або їхній інструмент пошуку "Constancia de Inscripción". AFIP пропонує API для автоматизованої перевірки, хоча вам потрібно зареєструватися як розробнику та пройти автентифікацію. У виробничих середовищах реалізуйте обидва рівні: спочатку виконайте алгоритмічну перевірку (швидко, виявляє помилки друку та формату), потім перевірте за базою даних AFIP (повільніше, але підтверджує реальність і активність номера). ### Чи можу я використати цей інструмент у комерційному додатку? Так — алгоритм перевірки CUIT/CUIL є публічним стандартом, визначеним AFIP, тому ви можете вільно впроваджувати його в комерційне програмне забезпечення. Надані тут приклади коду призначені як еталонні реалізації. Для використання у виробництві зверніть увагу на такі кращі практики: реалізуйте належну обробку помилок для крайніх випадків, додайте журналювання для налагодження збоїв перевірки, перевіряйте за офіційною базою даних AFIP (а не лише за алгоритмічною перевіркою), і тримайте реалізацію актуальною, якщо AFIP змінить правила (хоча поточний алгоритм є стабільним протягом десятиліть). ### Чи зберігає інструмент згенеровані або перевірені номери CUIT/CUIL? Ні — вся обробка відбувається у вашому браузері (на стороні клієнта). Коли ви генеруєте або перевіряєте CUIT/CUIL, обчислення виконуються локально за допомогою JavaScript. Нічого не надсилається на наші сервери, і ми не реєструємо, не зберігаємо та не відстежуємо жодних номерів, які ви вводите або генеруєте. Цей підхід на стороні клієнта забезпечує приватність і також означає, що інструмент працює офлайн після завантаження сторінки. Ви можете перевірити це, відкривши інструменти розробника у браузері та спостерігаючи за вкладкою мережі — ви не побачите жодних запитів при генерації або перевірці номерів. ## Посилання 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, які вам потрібні. Генеруйте тестові дані, які проходять алгоритмічну перевірку, перевіряйте номери перед їх потраплянням до бази даних або досліджуйте, як працює алгоритм контрольної цифри на практиці.