Прескочи към съдържанието

Генератор и валидатор на CUIT/CUIL | Инструмент за данъчно ID на Аржентина

Генерирайте валидни тестови номера на CUIT/CUIL за Аржентина или валидирайте съществуващи такива. Безплатен онлайн инструмент за разработчици, тестващи данъчни ID и системи за работни заплати с валидация, съвместима с AFIP.

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

Въведете 8-цифрен DNI номер или използвайте случайния генератор

Генериран CUIT/CUIL
20-65269295-9

Използване на случайно генериран 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_i е ii-тата цифра от първите 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. Много имплементации преобразуват към цели числа за обработка, което премахва водещите нули. Използвайте string операции с правилно допълване.

Объркване с кодовете за тип: Не всички двуцифрени числа са валидни кодове за тип. Само 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. Тестването на тези правила за валидация изисква номера, които преминават алгоритъма за контролна цифра.
  • HR управленски системи: Обработката на заплати и социалните осигуровки зависят от валидни CUIL номера. Често срещан сценарий: тествате процеси по включване на служители и трябва да проверите дали невалидните CUIL номера предизвикват подходящи съобщения за грешка.
  • Банкови приложения: KYC (Познай своя клиент) процесите валидират CUIT/CUIL като част от отварянето на сметка. По мой опит, гранични случаи като несъответствия в кодовете на типа често се появяват по време на интеграционно тестване.

Попълване на бази данни: При засяване на тестови бази данни, използването на алгоритмично валидни CUIT/CUIL номера гарантира, че ограниченията и тригерите на базата данни работят според очакванията. Това е особено важно при тестване на скриптове за миграция на данни или ETL процеси, които валидират идентификационни номера.

Тестване на валидация на формуляри: Тествайте както щастливия сценарий, така и условията за грешка. Генерирайте валидни номера, за да потвърдите успешно подаване, след това модифицирайте контролната цифра, за да гарантирате, че вашата предна и задна част улавят грешката преди да достигне до базата данни.

API тестване: Интеграционните тестове трябва да използват валидни CUIT/CUIL номера в полезните товари на заявките. Това предотвратява фалшиви отрицателни резултати, където тестовете се провалят поради невалидни тестови данни, а не поради действителни бъгове в логиката на API.

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

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

Изучаване на валидационни алгоритми: Алгоритъмът за проверка на CUIT/CUIL демонстрира практическо приложение на модулна аритметика и тежестни контролни цифри. Същият модел се среща и в други системи за идентификация по света — номерата на кредитни карти (алгоритъм на Лун), ISBN кодове и европейски ДДС номера, които използват подобни подходи с тежестни контролни суми. Разбирането как работи валидацията на CUIT/CUIL дава представа защо съществуват тези алгоритми: те улавят грешки при преписване като разменени цифри или еднократни грешки.

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

Международно бизнес развитие: Ако изграждате системи за латиноамерикански пазари, разбирането на CUIT/CUIL ви помага да схванете подобни системи в съседни страни. Бразилия има CPF/CNPJ, Чили има RUT, Уругвай има RUT — всички използват алгоритми с контролни цифри. Моделите, които научите тук, се пренасят към тези системи.

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

Докато този инструмент работи добре за разработка и тестване, производствените среди имат различни изисквания:

Официална държавна валидация: За живи приложения, алгоритмичната валидация сама по себе си не е достатъчна — трябва да проверите дали CUIT/CUIL е действително регистриран в AFIP (Администрация на федералните данъчни приходи). 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) беше първоначално въведен в Аржентина през 70-те години като част от усилията за модернизиране на данъчната система за събиране. Федералната администрация за публични приходи (AFIP) въведе този уникален идентификатор, за да проследява данъкоплатците по-ефективно и да намали данъчните измами.

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

Еволюция и дигитализация

През 90-те години, когато Аржентина преминава през значителни икономически реформи, системата CUIT/CUIL става все по-важна за проследяване на икономическата дейност. Системата беше допълнително дигитализирана и бяха въведени онлайн системи за проверка.

В началото на 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 проверката с подходящи TTL (обикновено 24 часа), за да балансирате актуалността с производителността.

Кодиране на символи: При обработка на CUIT/CUIL данни от външни източници (PDF, сканирани документи, уеб скрейпинг), бъдете внимателни с проблеми при кодирането на символи. Тирето може да се появи като em тире (U+2014), en тире (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' => 'Невалиден формат']; } ## Често задавани въпроси ### Каква е разликата между 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 с личната си карта, докато фирмите трябва да завършат процедурите по корпоративна регистрация. Инструментът е строго за разработка, тестване и образователни цели, когато са необходими валидни данни, които няма да влизат в конфликт с реални идентификационни номера. ### Защо моята CUIT/CUIL валидация се проваля, въпреки че форматът изглежда правилен? Когато валидацията се провали, въпреки че форматът изглежда правилен, проверете тези чести причини: 1. **Невалиден типов код**: Само 20, 23, 24, 27, 30, 33, 34 са валидни. Използването на 21, 25 или други числа ще предизвика грешка. 2. **Грешна контролна цифра**: Последната цифра трябва да отговаря на изчислението по алгоритъма. Дори промяната на една цифра в частта с личната карта изисква преизчисляване на контролната цифра. 3. **Проблеми с форматирането**: Трябва да са точно 11 цифри (XX-XXXXXXXX-X). Внимавайте за допълнителни интервали или липсващи водещи нули. 4. **Скрити знаци**: Копирането от PDF или уебсайтове понякога въвежда невидими Unicode знаци, които нарушават валидирането. Бърз съвет за отстраняване на грешки: премахнете последната цифра и я изчислете ръчно. Ако не съвпада, това е вашата причина. ### Задължителни ли са тирета в CUIT/CUIL номерата? Тиретата са само за визуално форматиране - те не са част от действителния номер при изчисленията. Когато видите **20-12345678-9**, алгоритъмът се интересува само от 11-те цифри: **20123456789**. Повечето имплементации за валидация премахват тиретата преди обработката, което е причината нашият инструмент да приема както **20-12345678-9**, така и **20123456789**. В API-та и бази данни обикновено се съхранява версията без тирета и те се добавят само при показване на потребителите. Този подход предотвратява проблеми с валидацията, причинени от несъответствия във форматирането. ### Може ли CUIT/CUIL номер да има по-малко от 8 цифри в частта с личната карта? Частта с личната карта винаги трябва да е точно 8 цифри - без изключения. Ако действителната лична карта има по-малко цифри (което се случва при по-стари, по-ниски номера), се допълва с водещи нули. Например, лична карта **1234567** става **01234567** в структурата на CUIT/CUIL. Това е чест източник на грешки при преобразуване между лична карта и 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, от които се нуждаете. Генерирайте тестови данни, които преминават алгоритмична валидация, проверявайте номера преди те да влязат във вашата база данни или проучвайте как работи алгоритъмът за контролна цифра на практика.