Generator i validator CUIT/CUIL-a | Alat za porezni ID Argentine
Generirajte valjane testne brojeve CUIT/CUIL-a Argentine ili provjerite postojeće. Besplatan mrežni alat za razvojne programere koji testiraju porezni ID i sustave plaća s AFIP-ovom provjerom valjanosti.
Generator CUIT/CUIL-a
Unesite 8-znamenkasti DNI broj ili koristite nasumični generator
Koristi nasumično generirani DNI
Dokumentacija
Generator i validator argentinskog CUIT/CUIL broja
Uvod
U argentinskim poreznim i radnim sustavima, konstantno ćete nailaziti na dva ključna identifikatora: CUIT (Clave Única de Identificación Tributaria) i CUIL (Clave Única de Identificación Laboral). Zamislite CUIT kao porezni ID za tvrtke i pojedince koji plaćaju porez, dok CUIL identificira radnike u sustavu socijalne sigurnosti. Oba koriste isti 11-znamenkasti format i algoritam provjere, što čini testiranje aplikacija koje rukuju ovim brojevima osobito važnim.
Prilikom razvoja softvera za argentinsko tržište, potrebni su vam valjani testni podaci. Upravo tu dolazi ovaj alat. Možete generirati matematički ispravne CUIT/CUIL brojeve za testiranje bez korištenja pravih osobnih informacija ili provjeriti postojeće brojeve kako biste osigurali da odgovaraju službenom algoritmu AFIP-a. Osobito je korisno što alat pokriva obje strane - generiranje (stvaranje valjanih brojeva na zahtjev) i validaciju (otkrivanje pogrešaka u formatu, nevažećih kodova vrste i netočnih verificiranih znamenki prije nego što uzrokuju probleme u produkciji).
Struktura i izračun CUIT/CUIL broja
Razumijevanje formata
Valjan CUIT/CUIL broj sastoji se od 11 znamenki koje se tipično prikazuju u formatu XX-XXXXXXXX-X. Evo kako se razlaže:
-
Kod tipa (prva 2 znamenke): Identificira vrstu subjekta
- 20, 23, 24: Muški pojedinci (CUIL)
- 27: Ženske osobe (CUIL)
- 30, 33, 34: Tvrtke i organizacije (CUIT)
-
DNI broj (srednje 8 znamenki): Za pojedince, ovo je njihov nacionalni identifikacijski dokument (DNI). Česta zamka: ako DNI ima manje od 8 znamenki, morate ga nadopuniti vodećim nulama. Na primjer, DNI 1234567 postaje 01234567 u CUIT/CUIL-u. Tvrtke umjesto toga dobivaju dodijeljeni jedinstveni broj.
-
Kontrolna znamenka (zadnja znamenka): Ova kontrolna znamenka provjerava valjanost cijelog broja pomoću ponderiranog algoritma. Ako se ova znamenka ne podudara s izračunom, cijeli CUIT/CUIL je nevažeći - nešto što često iznenadi razvojne programere kada ručno konstruiraju testne podatke.
Izračun kontrolne znamenke
Kontrolna znamenka koristi modulo-11 pondetirani algoritam. Evo kako to funkcionira:
- Uzmite prvih 10 znamenki CUIT/CUIL-a (kod tipa + DNI)
- Pomnožite svaku znamenku njezinim odgovarajućim ponderom: 5, 4, 3, 2, 7, 6, 5, 4, 3, 2
- Zbrojite sve produkte
- Izračunajte: 11 minus (zbroj modulo 11)
- Obradite rubne slučajeve: ako je rezultat 11, koristite 0; ako je 10, koristite 9
Ono što ljude najčešće zbunjuje su upravo rubni slučajevi u koraku 5. Prilikom testiranja povremeno ćete dobiti rezultat od 10 ili 11, a zaboravljanje mapiranja ovih vrijednosti na 9 i 0 uzrokuje pogreške validacije koje mogu biti teške za ispravljanje ako niste svjesni ovog pravila.
Matematički, ovo se može izraziti kao:
Gdje:
- je kontrolna znamenka
- je -ta znamenka prvih 10 znamenki
- je odgovarajući ponder iz niza [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
- Posebni slučajevi: ako je onda je , ako je onda je
Vodič korak po korak
Korištenje Generatora
-
Odaberite karticu "Generator" na vrhu sučelja alata.
-
Odaberite Kod Tipa iz padajućeg izbornika:
- 20: Muško (CUIL)
- 23: Poslovno (CUIT)
- 24: Privremeno poslovno (CUIT)
- 27: Žensko (CUIL)
- 30: Korporacija (CUIT)
- 33: Civilno udruženje (CUIT)
- 34: Zaklada (CUIT)
-
Unesite DNI broj (opcionalno):
- Unesite 8-znamenkasti DNI broj u predviđeno polje
- Ako je ostavljeno prazno, alat će koristiti nasumično generirani DNI
- Ako unesete manje od 8 znamenki, sustav će dodati vodećih nula
-
Generiraj nasumični DNI (opcionalno):
- Kliknite gumb "Nasumično" za generiranje nasumičnog 8-znamenkastog DNI broja
-
Pogledaj generirani CUIT/CUIL:
- Alat automatski prikazuje valjan CUIT/CUIL na temelju vaših unosa
- Format će biti XX-XXXXXXXX-X s ispravnom kontrolnom znamenkom
-
Kopiraj rezultat:
- Kliknite ikonu kopiranja za kopiranje generiranog CUIT/CUIL-a u međuspremnik
- Pojavit će se potvrda kada je kopiranje uspješno
Korištenje Validatora
-
Odaberite karticu "Validator" na vrhu sučelja alata.
-
Unesite CUIT/CUIL za validaciju:
- Unesite CUIT/CUIL u formatu XX-XXXXXXXX-X
- Alat će automatski formatirati vaš unos s crtama dok tipkate
- Možete unijeti i broj bez crta (XXXXXXXXXXX)
-
Kliknite gumb "Validate":
- Alat će provjeriti format, kod tipa i kontrolnu znamenku
-
Pogledaj rezultat validacije:
- Za valjane CUIT/CUIL brojeve, pojavit će se zelena poruka uspjeha
- Za nevaljane brojeve, pojavit će se crvena poruka pogreške koja objašnjava problem:
- Nevažeći format (mora biti XX-XXXXXXXX-X)
- Nevažeći kod tipa (mora biti jedan od: 20, 23, 24, 27, 30, 33, 34)
- Nevažeća kontrolna znamenka
-
Dodatne informacije:
- Za valjane brojeve, alat prikazuje razradu komponenti:
- Kod tipa i njegovo značenje
- DNI broj
- Kontrolna znamenka
- Za valjane brojeve, alat prikazuje razradu komponenti:
Uobičajene pogreške i najbolje prakse
Kada radite s validacijom CUIT/CUIL brojeva u svojim aplikacijama, pazite na ove česte zamke:
Problemi s nulama ispred: Najčešća greška koju sam susreo uključuje DNI brojeve s vodećim nulama. Kada netko unese DNI "1234567", vaš kod treba tretirati kao "01234567" za CUIT/CUIL konstrukciju. Mnoge implementacije pretvaraju u cijele brojeve za obradu, što briše vodeće nule. Umjesto toga koristite string operacije s pravilnim nadopunjavanjem.
Konfuzija s kodovima tipa: Nisu svi dvoznamenkasti brojevi valjani kodovi tipa. Samo 20, 23, 24, 27, 30, 33, 34 funkcioniraju. Vidio sam sustave koji prihvaćaju bilo koji dvoznamenkasti prefiks, što dovodi do "validno izgledajućih" brojeva poput 21-12345678-X koji ne prolaze AFIP validaciju. Uvijek provjerite kod tipa prije izračuna kontrolne znamenke.
Pretpostavke o spolu: Kodovi tipa 20 (muški) i 27 (ženski) nisu međusobno zamjenjivi. Ako automatski generirate CUIL brojeve na temelju demografskih podataka, osigurajte da vaš kod tipa odgovara stvarnom spolu registriranom u RENAPER-u (nacionalni registar Argentine). Nepodudaranja uzrokuju odbijanje kada pojedinci pokušavaju koristiti ove brojeve u državnim uslugama.
Rukovanje crticama: Neke implementacije zahtijevaju crtice, dok ih druge odbacuju. Najbolja praksa: prihvatite oba formata u poljima za unos (s crticama ili bez njih), uklonite crtice prije validacije, spremite verziju bez crtica u baze podataka i dodajte crtice samo za prikaz.
Nedostajuća provjera: Algoritamska validacija hvata formatske pogreške, ali ne potvrđuje je li CUIT/CUIL registriran. U produkciji, prvo provjerite format (brzo), zatim verificirajte u AFIP-ovoj bazi podataka (sporije, ali mjerodavno). Ovaj dvostupanjski pristup trenutačno hvata tipfelerske pogreške, istovremeno osiguravajući da je broj stvaran.
Testiranje rubnih slučajeva: Uvijek testirajte s kontrolnim znamenkama 0 i 9 - one proizlaze iz posebnih slučajeva u algoritmu. Također testirajte DNI brojeve koji počinju nulama kako biste osigurali da vaša logika nadopunjavanja ispravno funkcionira.
Slučajevi upotrebe i praktične primjene
Razvoj i testiranje
Razvoj softvera: Prilikom izgradnje aplikacija za argentinsko tržište, trebat ćete testne podatke koji prolaze validaciju bez korištenja pravih korisničkih informacija. Evo gdje ovo postaje kritično:
- E-commerce platforme: Procesori plaćanja i sustavi fakturiranja zahtijevaju valjane CUIT/CUIL brojeve. Tijekom testiranja opterećenja, možda ćete trebati tisuće valjanih brojeva za simulaciju realnih korisničkih registracija.
- Računovodstveni softver: Moduli za porezno izvješćivanje provjeravaju CUIT/CUIL format prije podnošenja AFIP-u. Testiranje ovih pravila validacije zahtijeva brojeve koji prolaze algoritam provjere znamenke.
- Sustavi za upravljanje ljudskim resursima: Obrada plaća i doprinosa socijalnog osiguranja ovise o valjanim CUIL brojevima. Uobičajen scenarij: testirate tokove zapošljavanja zaposlenika i trebate provjeriti da li neispravni CUIL-ovi aktiviraju odgovarajuće poruke pogreške.
- Bankarske aplikacije: KYC (Upoznaj svog kupca) procesi validiraju CUIT/CUIL kao dio otvaranja računa. Iz mog iskustva, rubni slučajevi poput nepodudaranja kodova tipa često se pojavljuju tijekom integracijskog testiranja.
Punjenje baze podataka: Prilikom zasađivanja testnih baza podataka, korištenje algoritmički valjanih CUIT/CUIL brojeva osigurava da ograničenja i okidači vaše baze podataka rade kako je očekivano. Ovo je posebno važno prilikom testiranja skripti za migraciju podataka ili ETL procesa koji validiraju identifikacijske brojeve.
Testiranje validacije obrasca: Testirajte i sretne scenarije i uvjete pogreške. Generirajte valjane brojeve za potvrdu uspješne predaje, zatim modificirajte znamenku provjere kako biste osigurali da vaša frontend i backend validacija uhvati pogrešku prije nego što dosegne bazu podataka.
API testiranje: Integrativni testovi trebaju koristiti valjane CUIT/CUIL brojeve u payload-ovima zahtjeva. Ovo sprečava lažno negativne rezultate gdje testovi ne uspijevaju zbog nevaljanih testnih podataka, umjesto stvarnih grešaka u logici API-ja.
QA automatizacija: Parametrizirani testovi koristi dinamičko generiranje CUIT/CUIL brojeva. Umjesto hardcodiranja testnih vrijednosti koje se mogu sukobljavati između testnih pokretanja, generirajte nove valjane brojeve za svako izvršenje testa.
Obrazovne svrhe
Učenje algoritama validacije: CUIT/CUIL algoritam provjere demonstrira praktičnu primjenu modulnog aritmetičkog i ponderiranog provjere znamenki. Isti uzorak pojavljuje se u drugim sustavima identifikacije širom svijeta — brojevi kreditnih kartica (Luhn algoritam), ISBN kodovi i europski PDV brojevi svi koriste slične ponderirane checksume. Razumijevanje načina rada CUIT/CUIL validacije pruža uvid u razlog postojanja ovih algoritama: hvataju pogreške prijepisa poput zamijenjenih znamenki ili pogrešaka u jednoj znamenki.
Podučavanje validacije podataka: Prilikom obuke mlađih razvojnih inženjera o validaciji unosa, CUIT/CUIL sustav nudi primjer iz stvarnog života koji je složeniji od validacije e-pošte, ali jednostavniji od kriptografske provjere. Demonstrira načelo obrane u dubini: validacija formata (11 znamenki), validacija poslovnih pravila (valjani kodovi tipa) i algoritmička validacija (provjera znamenke).
Međunarodni razvoj poslovanja: Ako gradite sustave za latinskoameričko tržište, razumijevanje CUIT/CUIL-a pomaže vam shvatiti slične sustave u susjednim zemljama. Brazil ima CPF/CNPJ, Čile ima RUT, a Urugvaj ima RUT — svi koriste algoritme provjere znamenki. Obrasci koje ovdje naučite prenose se na te sustave.
Alternative i razmatranja za produkciju
Dok ovaj alat dobro funkcionira za razvoj i testiranje, produkcijska okruženja imaju drugačije zahtjeve:
Službena državna validacija: Za aktivne aplikacije, algoritmička validacija sama po sebi nije dovoljna — trebate provjeriti je li CUIT/CUIL zaista registriran kod AFIP-a (Administración Federal de Ingresos Públicos). AFIP pruža web servise za validaciju u stvarnom vremenu, ali ćete se morati registrirati i autenticirati da biste im pristupili. Kvaka je u tome da broj može biti matematički valjan, ali ne i službeno dodijeljen, stoga uvijek implementirajte oba sloja validacije u produkciji.
Biblioteke i paketi: Ako integrirate CUIT/CUIL validaciju u svoj kod, razmotrite ove etablirane biblioteke umjesto da sami izrađujete:
- JavaScript:
validar-cuitna npm-u rukuje validacijom i formatiranjem - PHP:
afip-phpbiblioteka pruža validaciju i AFIP web servis integraciju - Python:
py-cuitna PyPI-ju implementira kompletan algoritam
Korištenje održavanih biblioteka smanjuje rizik od implementacijskih grešaka i često uključuje rubne slučajeve koje biste mogli propustiti u prilagođenom kodu.
Ručni izračun: U svrhe učenja ili otklanjanja grešaka, ručni rad kroz algoritam pomaže učvršćivanju razumijevanja. Uzmite kalkulator i primjer CUIT/CUIL-a, zatim slijedite proces ponderiranog množenja korak po korak.
Enterprise usluge validacije: Velike aplikacije mogu imati koristi od API-ja za validaciju treće strane koji ne samo da provjeravaju format, već i unakrsno referiraju komercijalne baze podataka. Ove usluge mogu označiti neaktivne tvrtke, identificirati sankcionirane subjekte ili pružiti dodatne metapodatke o nositelju CUIT/CUIL-a.
Povijest CUIT/CUIL sustava
CUIT/CUIL identifikacijski sustav u Argentini značajno se razvio od svog nastanka:
Porijeklo i implementacija
CUIT (Clave Única de Identificación Tributaria) prvi put je uveden u Argentini 1970-ih kao dio napora za modernizaciju sustava prikupljanja poreza. Savezna uprava javnih prihoda (AFIP) implementirala je ovaj jedinstveni identifikator za učinkovitije praćenje poreznih obveznika i smanjenje porezne utaje.
CUIL (Clave Única de Identificación Laboral) naknadno je uveden za specifično identificiranje radnika u sustavu socijalne sigurnosti, stvarajući razliku između porezne identifikacije i radne identifikacije uz zadržavanje konzistentnog formata.
Evolucija i digitalizacija
Devedesetih godina, kada je Argentina prolazila kroz značajne ekonomske reforme, CUIT/CUIL sustav je postajao sve važniji za praćenje ekonomske aktivnosti. Sustav je dalje digitaliziran, a implementirani su i online sustavi provjere.
Početkom 2000-ih došlo je do integracije CUIT/CUIL sustava s različitim digitalnim državnim uslugama, čineći ga ključnom komponentom argentinskih e-vlada inicijativa. U ovom periodu također je standardiziran algoritam provjere i format koji se koristi i danas.
Nedavni razvoji
Posljednjih godina AFIP je poboljšao sigurnosne i verificijske procese za CUIT/CUIL brojeve, implementirajući sofisticiranije sustave validacije i integrirajući ih s ostalim državnim bazama podataka. Sustav sada igra ključnu ulogu u argentinskim naporima za borbu protiv porezne utaje i formalizaciju ekonomije.
Danas se CUIT/CUIL koristi ne samo za porezne i zaposlene svrhe, već i za širok raspon aktivnosti uključujući bankarstvo, nekretninske transakcije, komunalne usluge i online kupnje, čineći ga ključnim identifikatorom za pojedince i tvrtke koje posluju u Argentini.
Razmatranja pri implementaciji
Prilikom implementacije provjere CUIT/CUIL u vlastitim sustavima, razmotrite ove tehničke aspekte:
Stabilnost algoritma: Trenutni algoritam provjere CUIT/CUIL ostao je nepromijenjen od svoje standardizacije 1990-ih. Prema tehničkoj dokumentaciji AFIP-a, pristup provjere kontrolne znamenke modulo-11 kodificiran je u Resolución General 2854/2010 i naknadnim propisima. Ova stabilnost znači da implementacije rijetko zahtijevaju ažuriranja, ali trebate pratiti AFIP-ova obavješćivanja o bilo kakvim regulatornim promjenama.
Optimizacija performansi: Algoritam provjere računalno je jeftin - samo 10 množenja, jedan zbrajanje i jedna modulo operacija. Za sustave visokog protoka koji obrađuju tisuće provjera u sekundi, usko grlo je tipično mrežna latencija pri provjeri u AFIP-ovoj bazi podataka, a ne sam algoritam. Razmotrite spremanje rezultata AFIP provjere s odgovarajućim TTL-ovima (tipično 24 sata) kako biste uravnotežili svježinu i performanse.
Kodiranje znakova: Prilikom obrade CUIT/CUIL podataka iz vanjskih izvora (PDF-ovi, skenirani dokumenti, web skraperstvo), pazite na probleme kodiranja znakova. Crtica se može pojaviti kao em dash (U+2014), en dash (U+2013) ili minus znak (U+2212) umjesto standardne crte-minus (U+002D). Normalizirajte ih prije provjere kako biste spriječili lažno negativne rezultate.
Internacionalizacija: Ako vaša aplikacija služi više latinoameričkih tržišta, imajte na umu da argentinski CUIT/CUIL koristi modulo-11 s određenim ponderima, dok čileanski RUT koristi modulo-11 s drugačijim ponderima, a brazilski CPF/CNPJ koristi modulo-11 s još jednim drugačijim obrascem. Ne pretpostavljajte da su algoritmi identični - svaki državni sustav ima različita pravila. Za šire razumijevanje algoritama kontrolnih znamenki, pogledajte ISO/IEC 7064 standard koji formalizira različite modulo-bazne sheme provjere.
Pohrana u bazi podataka: Spremajte CUIT/CUIL brojeve bez crtica kao fiksne duljine CHAR(11) ili kao BIGINT ako vaša baza podataka podržava 11-znamenkaste cijele brojeve bez gubitka preciznosti. Dodajte ograničenje provjere koje provjerava kontrolnu znamenku na razini baze podataka kao sigurnosnu mrežu protiv oštećenih podataka. Stvorite indekse na ovom polju za učinkovito pretraživanje kada korisnici traže po CUIT/CUIL-u.
Primjeri koda
Python
1def calculate_verification_digit(type_code, dni):
2 # Pretvori u string i osiguraj da DNI ima 8 znamenki s vodećim nulama
3 type_code_str = str(type_code)
4 dni_str = str(dni).zfill(8)
5
6 # Kombiniraj tip koda i DNI
7 digits = type_code_str + dni_str
8
9 # Težine za svaku poziciju
10 weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
11
12 # Izračunaj sumu umnožaka
13 sum_products = sum(int(digits[i]) * weights[i] for i in range(10))
14
15 # Izračunaj kontrolnu znamenku
16 verification_digit = 11 - (sum_products % 11)
17
18 # Posebni slučajevi
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 # Valjani tipovi kodova
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"Nevažeći tip koda. Mora biti jedan od: {valid_type_codes}")
34
35 # Generiraj nasumičan DNI ako nije naveden
36 if dni is None:
37 dni = random.randint(10000000, 99999999)
38
39 # Izračunaj kontrolnu znamenku
40 verification_digit = calculate_verification_digit(type_code, dni)
41
42 # Formatiraj CUIT/CUIL
43 return f"{type_code}-{str(dni).zfill(8)}-{verification_digit}"
44
45def validate_cuit_cuil(cuit_cuil):
46 # Ukloni crtice ako su prisutne
47 cuit_cuil_clean = cuit_cuil.replace("-", "")
48
49 # Provjeri osnovni format
50 if not cuit_cuil_clean.isdigit() or len(cuit_cuil_clean) != 11:
51 return False, "Nevažeći format"
52
53 # Izdvoji dijelove
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 # Validiraj tip koda
59 valid_type_codes = [20, 23, 24, 27, 30, 33, 34]
60 if type_code not in valid_type_codes:
61 return False, "Nevažeći tip koda"
62
63 # Izračunaj i usporedi kontrolnu znamenku
64 calculated_digit = calculate_verification_digit(type_code, dni)
65 if calculated_digit != verification_digit:
66 return False, "Nevažeća kontrolna znamenka"
67
68 return True, "Valjan CUIT/CUIL"
69
70# Primjer upotrebe
71print(generate_cuit_cuil(20, 12345678)) # Generiraj za specifični DNI
72print(generate_cuit_cuil(27)) # Generiraj s nasumičnim DNI-jem
73print(validate_cuit_cuil("20-12345678-9")) # Validiraj CUIT/CUIL
74JavaScript
1function calculateVerificationDigit(typeCode, dni) {
2 // Pretvori u string i osiguraj da DNI ima 8 znamenki s vodećim nulama
3 const typeCodeStr = typeCode.toString();
4 const dniStr = dni.toString().padStart(8, '0');
5
6 // Kombiniraj tip koda i DNI
7 const digits = typeCodeStr + dniStr;
8
9 // Težine za svaku poziciju
10 const weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
11
12 // Izračunaj sumu umnožaka
13 let sumProducts = 0;
14 for (let i = 0; i < 10; i++) {
15 sumProducts += parseInt(digits[i]) * weights[i];
16 }
17
18 // Izračunaj kontrolnu znamenku
19 let verificationDigit = 11 - (sumProducts % 11);
20
21 // Posebni slučajevi
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 // Valjani tipovi kodova
33 const validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
34
35 if (!validTypeCodes.includes(typeCode)) {
36 throw new Error(`Nevažeći tip koda. Mora biti jedan od: ${validTypeCodes.join(', ')}`);
37 }
38
39 // Generiraj nasumičan DNI ako nije naveden
40 if (dni === undefined) {
41 dni = Math.floor(Math.random() * 90000000) + 10000000;
42 }
43
44 // Izračunaj kontrolnu znamenku
45 const verificationDigit = calculateVerificationDigit(typeCode, dni);
46
47 // Formatiraj CUIT/CUIL
48 return `${typeCode}-${dni.toString().padStart(8, '0')}-${verificationDigit}`;
49}
50
51function validateCuitCuil(cuitCuil) {
52 // Ukloni crtice ako su prisutne
53 const cuitCuilClean = cuitCuil.replace(/-/g, '');
54
55 // Provjeri osnovni format
56 if (!/^\d{11}$/.test(cuitCuilClean)) {
57 return { isValid: false, errorMessage: 'Nevažeći format' };
58 }
59
60 // Izdvoji dijelove
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 // Validiraj tip koda
66 const validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
67 if (!validTypeCodes.includes(typeCode)) {
68 return { isValid: false, errorMessage: 'Nevažeći tip koda' };
69 }
70
71 // Izračunaj i usporedi kontrolnu znamenku
72 const calculatedDigit = calculateVerificationDigit(typeCode, dni);
73 if (calculatedDigit !== verificationDigit) {
74 return { isValid: false, errorMessage: 'Nevažeća kontrolna znamenka' };
75 }
76
77 return { isValid: true };
78}
79
80// Primjer upotrebe
81console.log(generateCuitCuil(20, 12345678)); // Generiraj za specifični DNI
82console.log(generateCuitCuil(27)); // Generiraj s nasumičnim DNI-jem
83console.log(validateCuitCuil("20-12345678-9")); // Validiraj CUIT/CUIL
84Java
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 // Pretvori u string i osiguraj da DNI ima 8 znamenki s vodećim nulama
11 String typeCodeStr = String.valueOf(typeCode);
12 String dniStr = String.format("%08d", dni);
13
14 // Kombiniraj tip koda i DNI
15 String digits = typeCodeStr + dniStr;
16
17 // Izračunaj sumu umnožaka
18 int sumProducts = 0;
19 for (int i = 0; i < 10; i++) {
20 sumProducts += Character.getNumericValue(digits.charAt(i)) * WEIGHTS[i];
21 }
22
23 // Izračunaj kontrolnu znamenku
24 int verificationDigit = 11 - (sumProducts % 11);
25
26 // Posebni slučajevi
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("Nevažeći tip koda. Mora biti jedan od: " + VALID_TYPE_CODES);
39 }
40
41 // Generiraj nasumičan DNI ako nije naveden
42 if (dni == null) {
43 Random random = new Random();
44 dni = 10000000 + random.nextInt(90000000);
45 }
46
47 // Izračunaj kontrolnu znamenku
48 int verificationDigit = calculateVerificationDigit(typeCode, dni);
49
50 // Formatiraj CUIT/CUIL
51 return String.format("%d-%08d-%d", typeCode, dni, verificationDigit);
52 }
53
54 public static ValidationResult validateCuitCuil(String cuitCuil) {
55 // Ukloni crtice ako su prisutne
56 String cuitCuilClean = cuitCuil.replace("-", "");
57
58 // Provjeri osnovni format
59 if (!cuitCuilClean.matches("\\d{11}")) {
60 return new ValidationResult(false, "Nevažeći format");
61 }
62
63 // Izdvoji dijelove
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 // Validiraj tip koda
69 if (!VALID_TYPE_CODES.contains(typeCode)) {
70 return new ValidationResult(false, "Nevažeći tip koda");
71 }
72
73 // Izračunaj i usporedi kontrolnu znamenku
74 int calculatedDigit = calculateVerificationDigit(typeCode, dni);
75 if (calculatedDigit != verificationDigit) {
76 return new ValidationResult(false, "Nevažeća kontrolna znamenka");
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 // Primjer upotrebe
102 System.out.println(generateCuitCuil(20, 12345678)); // Generiraj za specifični DNI
103 System.out.println(generateCuitCuil(27, null)); // Generiraj s nasumičnim DNI-jem
104 System.out.println(validateCuitCuil("20-12345678-9").isValid()); // Validiraj CUIT/CUIL
105 }
106}
107PHP
<?php function calculateVerificationDigit($typeCode, $dni) { // Pretvori u string i osiguraj da DNI ima 8 znamenki s vodećim nulama $typeCodeStr = (string)$typeCode; $dniStr = str_pad((string)$dni, 8, '0', STR_PAD_LEFT); // Kombiniraj tip koda i DNI $digits = $typeCodeStr . $dniStr; // Težine za svaku poziciju $weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]; // Izračunaj sumu umnožaka $sumProducts = 0; for ($i = 0; $i < 10; $i++) { $sumProducts += (int)$digits[$i] * $weights[$i]; } // Izračunaj kontrolnu znamenku $verificationDigit = 11 - ($sumProducts % 11); // Posebni slučajevi if ($verificationDigit == 11) { $verificationDigit = 0; } else if ($verificationDigit == 10) { $verificationDigit = 9; } return $verificationDigit; } function generateCuitCuil($typeCode, $dni = null) { // Valjani tipovi kodova $validTypeCodes = [20, 23, 24, 27, 30, 33, 34]; if (!in_array($typeCode, $validTypeCodes)) { throw new Exception("Nevažeći tip koda. Mora biti jedan od: " . implode(', ', $validTypeCodes)); } // Generiraj nasumičan DNI ako nije naveden if ($dni === null) { $dni = rand(10000000, 99999999); } // Izračunaj kontrolnu znamenku $verificationDigit = calculateVerificationDigit($typeCode, $dni); // Formatiraj CUIT/CUIL return sprintf("%d-%08d-%d", $typeCode, $dni, $verificationDigit); } function validateCuitCuil($cuitCuil) { // Ukloni crtice ako su prisutne $cuitCuilClean = str_replace('-', '', $cuitCuil); // Provjeri osnovni format if (!preg_match('/^\d{11}$/', $cuitCuilClean)) { return ['isValid' => false, 'errorMessage' => 'Nevažeći format']; } // Izdvoji dijelove $typeCode = (int)substr($cuitCuilClean, 0, 2); $dni = (int)substr($cuitCuilClean, 2, 8); $verificationDigit = (int)substr($cuitCuilClean, 10, 1); // Validiraj tip koda $validTypeCodes = [20, 23, 24, 27, 30, 33, 34]; if (!in_array($typeCode, $validTypeCodes)) { return ['isValid' => false, 'errorMessage' => 'Nevažeći tip koda']; } // Izračunaj i usporedi kontrolnu znamenku $calculatedDig ## Često postavljana pitanja ### Koja je razlika između CUIT-a i CUIL-a? Evo praktične razlike: **CUIT** (Clave Única de Identificación Tributaria) identificira porezne obveznike - pojedince i tvrtke koje podnose porezne prijave AFIP-u. **CUIL** (Clave Única de Identificación Laboral) identificira radnike u sustavu socijalne sigurnosti za zapošljavanje i mirovinske svrhe. U praksi, mnogi pojedinci imaju i CUIL (od prvog posla) i mogu kasnije dobiti CUIT (ako postanu samostalni ili pokrenu posao). Brojevi koriste identično formatiranje i pravila izračuna, pa se s aspekta validacije tretiraju na isti način. Razlika je bitna za administrativne svrhe: sustavi plaća tipično rade s CUIL-om, dok sustavi fakturiranja i poreza koriste CUIT. ### Koje se vrste kodova koriste za pojedince, a koje za tvrtke? Za pojedince: - 20, 23, 24: Muški pojedinci (CUIL) - 27: Ženske osobe (CUIL) Za tvrtke i organizacije: - 30: Korporacije (CUIT) - 33: Civilne udruge (CUIT) - 34: Zaklade (CUIT) ### Kako se izračunava kontrolna znamenka? Algoritam koristi ponderiranu multipliciranju: uzmite prvih 10 znamenaka, pomnožite ponderima **5, 4, 3, 2, 7, 6, 5, 4, 3, 2**, zbrojite produkte, zatim izračunajte 11 minus (zbroj modulo 11). Dva rubna slučaja zbunjuju ljude: kada izračun daje 11, koristite 0 kao kontrolnu znamenku; kada daje 10, koristite 9. Ovi posebni slučajevi postoje jer kontrolna znamenka mora biti jednocifren broj (0-9). Ovo je algoritam provjere modulo-11, sličan onome koji se koristi u ISBN-10 kodovima i drugim sustavima identifikacije širom svijeta. ### Mogu li koristiti ovaj alat za generiranje pravih, službenih CUIT/CUIL brojeva? Ne - ovaj alat generira matematički valjane testne podatke, ali brojevi nisu službeno registrirani kod AFIP-a. Zamislite to kao generiranje valjanog broja kreditne kartice koristeći Luhn algoritam: prolazi provjeru formata, ali nije povezan s pravim računom. Za službenu CUIT/CUIL registraciju, pojedinci trebaju posjetiti AFIP s DNI-jem, dok tvrtke moraju završiti postupke registracije. Alat je isključivo za razvoj, testiranje i obrazovne svrhe gdje su potrebni valjani podaci koji neće biti u sukobu s pravim identifikacijskim brojevima. ### Zašto moja CUIT/CUIL validacija ne uspijeva čak i ako format izgleda ispravan? Kada validacija ne uspije unatoč ispravnom formatiranju, provjerite ove uobičajene krivce: 1. **Nevažeći kod vrste**: Samo su 20, 23, 24, 27, 30, 33, 34 valjani. Korištenje 21, 25 ili drugih brojeva će rezultirati neuspjehom. 2. **Pogrešna kontrolna znamenka**: Posljednja znamenka mora odgovarati izračunu algoritma. Čak i promjena jedne znamenke u DNI dijelu zahtijeva ponovni izračun kontrolne znamenke. 3. **Problemi s formatom**: Mora biti točno 11 znamenaka (XX-XXXXXXXX-X). Pazite na dodatne razmake ili nedostajuće vodećih nula. 4. **Skriveni znakovi**: Kopiranje i lijepljenje iz PDF-ova ili web stranica ponekad uvodi nevidljive Unicode znakove koji ruše validaciju. Brzi savjet za ispravljanje pogrešaka: uklonite posljednju znamenku i ručno je izračunajte. Ako ne odgovara, to je vaš krivac. ### Jesu li crtice potrebne u CUIT/CUIL brojevima? Crtice su samo za formatiranje prikaza - nisu dio stvarnog broja za izračun. Kada vidite **20-12345678-9**, algoritam brine samo o 11 znamenaka: **20123456789**. Većina implementacija validacije uklanja crtice prije obrade, zbog čega naš alat prihvaća i **20-12345678-9** i **20123456789**. U API-jima i bazama podataka, tipično ćete spremati broj bez crtica i dodavati ih samo prilikom prikaza korisnicima. Ovaj pristup sprečava nekonzistentnosti formatiranja koje bi mogle uzrokovati neuspjeh validacije. ### Može li CUIT/CUIL broj imati manje od 8 znamenaka u DNI dijelu? DNI dio uvijek mora biti točno 8 znamenaka - bez iznimki. Ako nečiji stvarni DNI ima manje znamenaka (što se događa sa starijim, nižim brojevima), dopunjavate vodećim nulama. Na primjer, DNI **1234567** postaje **01234567** u CUIT/CUIL strukturi. Ovo je čest izvor grešaka prilikom pretvaranja između DNI i CUIT/CUIL formata. Vidio sam sustave koji ne uspijevaju u validaciji jer su zaboravili dodati nule, tretirajući **1234567** kao sedmoznamenkasti broj umjesto **01234567**. Uvijek koristite funkcije za dodavanje nula umjesto jednostavnog spajanja nizova. ### Kako mogu provjeriti je li CUIT/CUIL službeno registriran u Argentini? Naš alat provjerava matematičku ispravnost - format, kod vrste i kontrolnu znamenku. Ali ne može reći je li broj stvarno registriran kod AFIP-a ili pripada pravoj osobi ili tvrtki. Za službenu provjeru, koristite [AFIP-ove web servise](https://www.afip.gob.ar/) ili njihov alat za pretraživanje "Constancia de Inscripción". AFIP nudi API-je za automatsku provjeru, ali trebat će vam registracija kao programera i autentifikacija. U produkcijskim okruženjima implementirajte oba sloja: prvo izvedite algoritmičku validaciju (brzo, hvata tipfelerske pogreške i formatne greške), zatim provjerite u AFIP-ovoj bazi podataka (sporije, ali potvrđuje da je broj stvaran i aktivan). ### Mogu li koristiti ovaj alat u svojoj komercijalnoj aplikaciji? Da - CUIT/CUIL algoritam validacije je javni standard koji definira AFIP, tako da ga možete slobodno implementirati u komercijalni softver. Primjeri koda ovdje su namijenjeni kao referentne implementacije. Za upotrebu u produkciji, razmotrite ove najbolje prakse: implementirajte pravilno rukovanje pogreškama za rubne slučajeve, dodajte logging za ispravljanje pogrešaka validacije, provjerite u AFIP-ovoj službenoj bazi podataka (ne samo algoritmičkom validacijom), i držite implementaciju ažurnom ako AFIP promijeni pravila (premda je trenutni algoritam stabilan već desetljećima). ### Sprema li alat generirane ili validirane CUIT/CUIL brojeve? Ne - sva obrada se odvija u vašem pregledniku (na strani klijenta). Kada generirate ili provjeravate CUIT/CUIL, izračun se izvodi lokalno koristeći JavaScript. Ništa se ne šalje na naše poslužitelje i ne bilježimo, ne pohranjujemo niti pratimo brojeve koje unesete ili generirate. Ovaj pristup na strani klijenta osigurava privatnost i također znači da alat radi i izvan mreže nakon učitavanja stranice. Možete provjeriti ovo otvaranjem razvojnih alata preglednika i promatranjem kartice mreže - nećete vidjeti zahtjeve poslane prilikom generiranja ili validacije brojeva. ## Reference 1. AFIP (Federalna uprava javnih prihoda). "CUIT/CUIL/CDI." Službena web stranica. [https://www.afip.gob.ar/](https://www.afip.gob.ar/) 2. Ministarstvo rada, zapošljavanja i socijalne sigurnosti. "CUIL - Jedinstveni identifikacijski ključ rada." [https://www.argentina.gob.ar/trabajo](https://www.argentina.gob.ar/trabajo) 3. ANSES (Nacionalna uprava socijalne sigurnosti). "Dobivanje mojeg CUIL-a." [https://www.anses.gob.ar/](https://www.anses.gob.ar/) 4. Službeni list Argentine Republike. "Opća rezolucija AFIP 2854/2010: Postupak. Jedinstveni porezni identifikacijski ključ (C.U.I.T.)." 5. Fiskalni zakonik Argentine Republike. "Identifikacija i registracija poreznih obveznika." --- Bez obzira radite li sustav za fakturiranje, testirate protoke zapošljavanja zaposlenika ili učite o algoritmima validacije, ovaj alat pruža generiranje i validaciju CUIT/CUIL-a koji vam je potreban. Generirajte testne podatke koji prolaze algoritmičku validaciju, provjerite brojeve prije nego što stignu u bazu podataka ili istražite kako algoritam provjerne znamenke funkcionira u praksi.