CUIT/CUIL Generator & Validator | Argentinsk skatte-ID-verktøy
Generer gyldige argentinske CUIT/CUIL testnumre eller valider eksisterende. Gratis online verktøy for utviklere som tester skatte-ID og lønnssystemer med AFIP-kompatibel validering.
CUIT/CUIL Generator
Skriv inn et 8-sifret DNI-nummer eller bruk den tilfeldige generatoren
Bruker tilfeldig generert DNI
Dokumentasjon
Argentinsk CUIT/CUIL Generator og Validator
Introduksjon
I Argentinas skatte- og arbeidssystemer vil du hele tiden støte på to kritiske identifikatorer: CUIT (Clave Única de Identificación Tributaria) og CUIL (Clave Única de Identificación Laboral). Tenk på CUIT som skatte-ID for bedrifter og enkeltpersoner som betaler skatt, mens CUIL identifiserer arbeidstakere i trygdesystemet. Begge bruker samme 11-sifrede format og verifiseringsalgoritme, noe som gjør testing av applikasjoner som håndterer disse numrene spesielt viktig.
Når du utvikler programvare for det argentinske markedet, trenger du gyldige testdata. Det er her dette verktøyet kommer inn. Du kan generere matematisk korrekte CUIT/CUIL-nummer for testing uten å bruke virkelig personlig informasjon, eller validere eksisterende nummer for å sikre at de overholder AFIPs offisielle algoritme. Det som er spesielt nyttig, er at verktøyet håndterer både genererings- (opprette gyldige nummer på forespørsel) og valideringssiden (fange formatfeil, ugyldige typekoder og feil verifiseringssifre før de forårsaker produksjonsproblemer).
CUIT/CUIL Struktur og Beregning
Forstå Formatet
Et gyldig CUIT/CUIL-nummer består av 11 sifre som vanligvis vises i formatet XX-XXXXXXXX-X. Slik brytes det ned:
-
Typekode (første 2 sifre): Identifiserer enhetstypen
- 20, 23, 24: Mannlige individer (CUIL)
- 27: Kvinnelige individer (CUIL)
- 30, 33, 34: Selskaper og organisasjoner (CUIT)
-
DNI-nummer (midterste 8 sifre): For individer er dette deres nasjonale identitetsdokumentnummer (DNI). En vanlig fallgruve: hvis den faktiske DNI-en har færre enn 8 sifre, må du fylle på med ledende nuller. For eksempel blir DNI 1234567 til 01234567 i CUIT/CUIL. Selskaper mottar i stedet et unikt tildelt nummer.
-
Kontrollsifre (siste sifre): Dette kontrollsifferet validerer hele nummeret ved hjelp av en vektet algoritme. Hvis dette sifferet ikke samsvarer med beregningen, er hele CUIT/CUIL ugyldig—noe som ofte overrasker utviklere når de manuelt konstruerer testdata.
Beregning av Kontrollsifre
Kontrollsifferet bruker en modulo-11 vektet algoritme. Slik fungerer den:
- Ta de første 10 sifrene i CUIT/CUIL (typekode + DNI)
- Multipliser hvert siffer med sin tilsvarende vekt: 5, 4, 3, 2, 7, 6, 5, 4, 3, 2
- Summer alle produktene
- Beregn: 11 minus (sum modulo 11)
- Håndter grensetilfeller: hvis resultatet er 11, bruk 0; hvis det er 10, bruk 9
Det som oftest forvirrer folk, er disse grensetilfellene i trinn 5. Når du tester, vil du av og til få et resultat på 10 eller 11, og glemme å kartlegge disse til 9 og 0 henholdsvis, forårsaker valideringssvikt som kan være vanskelig å feilsøke hvis du ikke er klar over denne regelen.
Matematisk kan dette uttrykkes som:
Hvor:
- er kontrollsifferet
- er det -te sifferet i de første 10 sifrene
- er den tilsvarende vekten fra sekvensen [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
- Spesialtilfeller: hvis da , hvis da
Trinnvis Veiledning
Bruke Generatoren
-
Velg "Generator"-fanen øverst i verktøygrensesnittet.
-
Velg en Typekode fra rullegardinmenyen:
- 20: Mann (CUIL)
- 23: Bedrift (CUIT)
- 24: Midlertidig Bedrift (CUIT)
- 27: Kvinne (CUIL)
- 30: Selskap (CUIT)
- 33: Sivil Forening (CUIT)
- 34: Stiftelse (CUIT)
-
Skriv inn et DNI-nummer (valgfritt):
- Legg inn et 8-sifret DNI-nummer i det angitte feltet
- Hvis det er tomt, vil verktøyet bruke et tilfeldig generert DNI
- Hvis du legger inn færre enn 8 sifre, vil systemet fylle på med ledende nuller
-
Generer Tilfeldig DNI (valgfritt):
- Klikk på "Tilfeldig"-knappen for å generere et tilfeldig 8-sifret DNI-nummer
-
Vis den Genererte CUIT/CUIL:
- Verktøyet viser automatisk en gyldig CUIT/CUIL basert på dine inndata
- Formatet vil være XX-XXXXXXXX-X med riktig kontrollsifre
-
Kopier Resultatet:
- Klikk på kopieringsikonet for å kopiere den genererte CUIT/CUIL til utklippstavlen
- En bekreftelsesmelding vil vises når den er kopiert
Bruke Validatoren
-
Velg "Validator"-fanen øverst i verktøygrensesnittet.
-
Skriv inn CUIT/CUIL som skal Valideres:
- Legg inn CUIT/CUIL i formatet XX-XXXXXXXX-X
- Verktøyet vil automatisk formatere inndata med bindestreker mens du skriver
- Du kan også legge inn nummeret uten bindestreker (XXXXXXXXXXX)
-
Klikk på "Valider"-knappen:
- Verktøyet vil sjekke format, typekode og kontrollsifre
-
Vis Valideringsresultatet:
- For gyldige CUIT/CUIL-nummer vil en grønn suksessmelding vises
- For ugyldige nummer vil en rød feilmelding forklare problemet:
- Ugyldig format (må være XX-XXXXXXXX-X)
- Ugyldig typekode (må være en av: 20, 23, 24, 27, 30, 33, 34)
- Ugyldig kontrollsifre
-
Tilleggsinformasjon:
- For gyldige nummer vil verktøyet vise en oversikt over komponentene:
- Typekode og dens betydning
- DNI-nummer
- Kontrollsifre
- For gyldige nummer vil verktøyet vise en oversikt over komponentene:
Vanlige feil og beste praksis
Når du arbeider med CUIT/CUIL-validering i dine applikasjoner, pass på disse hyppige fallgruvene:
Problemer med nullpading: Den vanligste feilen jeg har støtt på innebærer DNI-numre med ledende nuller. Når noen legger inn DNI "1234567", må koden din behandle det som "01234567" for CUIT/CUIL-konstruksjon. Mange implementasjoner konverterer til heltall for behandling, noe som fjerner ledende nuller. Bruk strengoperasjoner med riktig padding i stedet.
Forvirring rundt typekode: Ikke alle totalls-numre er gyldige typekoder. Kun 20, 23, 24, 27, 30, 33, 34 fungerer. Jeg har sett systemer som aksepterer hvilken som helst totalls-prefiks, noe som fører til "gyldig-utseende" numre som 21-12345678-X som mislykkes i AFIP-validering. Valider alltid typekoden før du beregner kontrollsifferet.
Kjønnsantakelser: Typekode 20 (mann) og 27 (kvinne) er ikke utbyttbare. Hvis du automatisk genererer CUILer basert på demografiske data, sørg for at typekoden matcher kjønnet som er registrert hos RENAPER (Argentinas nasjonale register). Avvik fører til avvisning når enkeltpersoner prøver å bruke disse numrene med statlige tjenester.
Bindestrekshåndtering: Noen implementasjoner krever bindestrek mens andre avviser dem. Beste praksis: aksepter begge formater i inntastingsfelt (med eller uten bindestrek), fjern bindestrek før validering, lagre den ubundne versjonen i databaser, og legg til bindestrek kun for visningsformål.
Manglende verifisering: Algoritmevalidering fanger opp formatfeil, men bekrefter ikke at CUIT/CUIL er registrert. I produksjon, valider format først (raskt), deretter verifiser mot AFIP-databasen (saktere men autoritativ). Denne totrinnstilnærmingen fanger opp skrivefeil umiddelbart samtidig som det sikres at nummeret er ekte.
Testing av grensetilfeller: Test alltid med kontrollsifre 0 og 9 - disse resulterer fra spesialtilfellene i algoritmen. Test også DNI-er som starter med nuller for å sikre at din padding-logikk fungerer korrekt.
Bruksområder og praktiske anvendelser
Utvikling og testing
Programvareutvikling: Når du bygger applikasjoner for det argentinske markedet, trenger du testdata som passerer validering uten å bruke virkelige brukeropplysninger. Her blir dette kritisk:
- E-handelplattformer: Betalingsprosessorer og faktureringssystemer krever gyldige CUIT/CUIL-nummer. Under belastningstesting kan du trenge tusenvis av gyldige nummer for å simulere realistiske brukerregistreringer.
- Regnskapsprogramvare: Skattemeldingsmoduler verifiserer CUIT/CUIL-format før innsending til AFIP. Testing av disse valideringsreglene krever nummer som passerer sjekksiffer-algoritmen.
- HR-administrasjonssystemer: Lønnsbehandling og sosiale trygdebidrag avhenger av gyldige CUIL-nummer. Et vanlig scenario: du tester ansettelsesflyter og trenger å verifisere at ugyldige CUILer utløser egnede feilmeldinger.
- Bankaplikasjoner: KYC-prosesser (Know Your Customer) validerer CUIT/CUIL som en del av kontoåpning. Etter min erfaring dukker grensetilfeller som type-kode-avvik ofte opp under integrasjonstesting.
Databasepopulasjon: Når du fyller testdatabaser, sikrer bruk av algoritmisk gyldige CUIT/CUIL-nummer at databasens begrensninger og utløsere fungerer som forventet. Dette er spesielt viktig ved testing av datamigrasjonsskript eller ETL-prosesser som validerer identifikasjonsnummer.
Skjemavalideringstesting: Test både den ideelle veien og feilbetingelser. Generer gyldige nummer for å bekrefte vellykket innsending, og modifiser så verifiseringssifrene for å sikre at frontend- og backend-validering fanger opp feilen før den når databasen.
API-testing: Integrasjonstester bør bruke gyldige CUIT/CUIL-nummer i forespørselspaylaster. Dette forhindrer falske negativer der tester mislykkes på grunn av ugyldige testdata i stedet for faktiske feil i API-logikken.
QA-automatisering: Parametriserte tester har nytte av dynamisk CUIT/CUIL-generering. I stedet for å hardkode testverdier som kan komme i konflikt på tvers av testkjøringer, generer nye gyldige nummer for hver testgjennomføring.
Pedagogiske formål
Læring av valideringsalgoritmer: CUIT/CUIL-verifikasjonsalgoritmen demonstrerer praktisk bruk av modulo-aritmetikk og vektede sjekksiffer. Samme mønster forekommer i andre identifikasjonssystemer verden over—kreditkortnummer (Luhn-algoritmen), ISBN-koder og europeiske MVA-nummer bruker alle lignende vektede kontrollsummetoder. Å forstå hvordan CUIT/CUIL-validering fungerer gir innsikt i hvorfor disse algoritmene eksisterer: de fanger opp transkripsjonsfeil som byttet sifre eller enkeltsiferfeil.
Opplæring i datavalidering: Når du trener junior-utviklere i inndatavalidering, tilbyr CUIT/CUIL-systemet et virkelig eksempel som er mer komplekst enn e-postvalidering, men enklere enn kryptografisk verifisering. Det demonstrerer prinsippet om forsvar i dybden: formatvalidering (11 sifre), forretningsregelvalidering (gyldige type-koder) og algoritmisk validering (sjekksiffer).
Internasjonal forretningsutvikling: Hvis du bygger systemer for latinamerikanske markeder, hjelper forståelsen av CUIT/CUIL deg med å forstå lignende systemer i naboland. Brasil har CPF/CNPJ, Chile har RUT, og Uruguay har RUT—alle bruker sjekksiffer-algoritmer. Mønstrene du lærer her, overfører seg til disse systemene.
Alternativer og produksjonshensyn
Mens dette verktøyet fungerer godt for utvikling og testing, har produksjonsmiljøer andre krav:
Offisiell statlig validering: For live-applikasjoner er algoritmisk validering alene ikke nok—du trenger å verifisere at CUIT/CUIL faktisk er registrert hos AFIP (Administración Federal de Ingresos Públicos). AFIP tilbyr webtjenester for sanntidsvalidering, selv om du må registrere og autentisere deg for å få tilgang. Poenget er: et nummer kan være matematisk gyldig, men ikke offisielt tildelt, så implementer alltid begge valideringslag i produksjon.
Biblioteker og pakker: Hvis du integrerer CUIT/CUIL-validering i kodegrunnlaget, bør du vurdere disse etablerte bibliotekene fremfor å lage dine egne:
- JavaScript:
validar-cuitpå npm håndterer validering og formatering - PHP:
afip-php-bibliotek tilbyr både validering og AFIP webtjeneste-integrasjon - Python:
py-cuitpå PyPI implementerer hele algoritmen
Bruk av vedlikeholdte biblioteker reduserer risikoen for implementasjonsfeil og inkluderer ofte kanttilfeller du kanskje ville gått glipp av i egendefinert kode.
Manuell beregning: For læring eller feilsøking hjelper det å arbeide gjennom algoritmen for hånd. Ta frem en kalkulator og et eksempel-CUIT/CUIL, og følg så den vektede multiplikasjonsprosessen trinn for trinn.
Enterprise valideringstjenester: Store applikasjoner kan ha nytte av tredjeparts validerings-APIer som ikke bare sjekker format, men også kryssrefererer mot kommersielle databaser. Disse tjenestene kan merke inaktive virksomheter, identifisere sanksjonsbelagte enheter eller gi ytterligere metadata om CUIT/CUIL-innehaveren.
Historien om CUIT/CUIL-systemet
CUIT/CUIL-identifikasjonssystemet i Argentina har utviklet seg betydelig siden oppstarten:
Opprinnelse og implementering
CUIT (Clave Única de Identificación Tributaria) ble først introdusert i Argentina på 1970-tallet som en del av arbeidet med å modernisere skattoppkrevingssystemet. Skatteetaten (AFIP) implementerte denne unike identifikatoren for å spore skattebetalere mer effektivt og redusere skatteunndragelse.
CUIL (Clave Única de Identificación Laboral) ble senere introdusert for å spesifikt identifisere arbeidstakere i trygdesystemet, og skape en distinksjon mellom skatte- og arbeidsidentifikasjon samtidig som man opprettholdt et konsistent format.
Utvikling og digitalisering
På 1990-tallet, da Argentina gjennomgikk betydelige økonomiske reformer, ble CUIT/CUIL-systemet stadig viktigere for å spore økonomisk aktivitet. Systemet ble ytterligere digitalisert, og online verifiseringssystemer ble implementert.
Begynnelsen av 2000-tallet så integreringen av CUIT/CUIL-systemet med ulike digitale statlige tjenester, noe som gjorde det til en vesentlig del av Argentinas e-forvaltningsinitiativer. Denne perioden så også standardiseringen av verifiseringsalgoritmen og formatet som fortsatt er i bruk i dag.
Nyere utvikling
I de senere årene har AFIP forbedret sikkerhets- og verifiseringsprosessene for CUIT/CUIL-numre, ved å implementere mer sofistikerte valideringssystemer og integrere dem med andre statlige databaser. Systemet spiller nå en avgjørende rolle i Argentinas innsats for å bekjempe skatteunndragelse og formalisere økonomien.
I dag brukes CUIT/CUIL ikke bare for skatte- og sysselsettingsformål, men også for et bredt spekter av aktiviteter, inkludert bankvirksomhet, eiendomstransaksjoner, forsyningstjenester og netthandel, noe som gjør det til en vesentlig identifikator for både enkeltpersoner og virksomheter som opererer i Argentina.
Implementeringshensyn
Ved implementering av CUIT/CUIL-validering i dine egne systemer, vurder disse tekniske aspektene:
Algoritme-stabilitet: Den nåværende CUIT/CUIL-verifiseringsalgoritmen har forbli uendret siden standardiseringen på 1990-tallet. I følge AFIP's tekniske dokumentasjon, er modulo-11 vektet sjekksiffer-tilnærmingen kodifisert i Resolución General 2854/2010 og etterfølgende forskrifter. Denne stabiliteten betyr at implementeringer sjelden trenger oppdateringer, men du bør overvåke AFIP-kunngjøringer for eventuelle regelendringer.
Ytelsesoptimalisering: Verifiseringsalgoritmen er beregningsmessig rimelig—bare 10 multiplikasjoner, én addisjon og én modulo-operasjon. For høykapasitetssystemer som behandler tusenvis av valideringer per sekund, er flaskehalsen typisk nettverksventetid ved verifisering mot AFIP's database, ikke algoritmen selv. Vurder å mellomlagre AFIP-verifikasjonsresultater med passende TTL-er (vanligvis 24 timer) for å balansere aktualitet med ytelse.
Tegnkoding: Ved behandling av CUIT/CUIL-data fra eksterne kilder (PDFer, skannede dokumenter, webscraping), vær oppmerksom på tegnkodingsproblemer. Bindestreken kan dukke opp som en em dash (U+2014), en dash (U+2013), eller minustegn (U+2212) i stedet for standard bindestrek-minus (U+002D). Normaliser disse før validering for å forhindre falske negativer.
Internasjonalisering: Hvis applikasjonen din betjener flere latinamerikanske markeder, merk at Argentinas CUIT/CUIL bruker modulo-11 med spesifikke vekter, mens Chiles RUT bruker modulo-11 med forskjellige vekter, og Brasils CPF/CNPJ bruker modulo-11 med en annen mønster. Ikke ta for gitt at algoritmene er identiske—hvert lands system har distinkte regler. For en bredere forståelse av sjekksiffer-algoritmer, se ISO/IEC 7064-standarden som formaliserer forskjellige modulo-baserte verifikasjonsskjemaer.
Databaselagring: Lagre CUIT/CUIL-numre uten bindestreker som fast lengde CHAR(11) eller som BIGINT hvis databasen din støtter 11-sifrede heltall uten presisjonsstap. Legg til en sjekkbetingelse som validerer verifiseringsssifferet på databasenivå som en sikkerhetsmekanisme mot korruperte data. Opprett indekser på dette feltet for effektive oppslag når brukere søker etter CUIT/CUIL.
Kodeeksempler
Python
1def calculate_verification_digit(type_code, dni):
2 # Konverter til streng og sikre at DNI er 8 sifre med ledende nuller
3 type_code_str = str(type_code)
4 dni_str = str(dni).zfill(8)
5
6 # Kombiner type-kode og DNI
7 digits = type_code_str + dni_str
8
9 # Vekter for hver posisjon
10 weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
11
12 # Beregn sum av produkter
13 sum_products = sum(int(digits[i]) * weights[i] for i in range(10))
14
15 # Beregn verifiseringssiffer
16 verification_digit = 11 - (sum_products % 11)
17
18 # Spesielle tilfeller
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 # Gyldige type-koder
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"Ugyldig type-kode. Må være en av: {valid_type_codes}")
34
35 # Generer tilfeldig DNI hvis ikke oppgitt
36 if dni is None:
37 dni = random.randint(10000000, 99999999)
38
39 # Beregn verifiseringssiffer
40 verification_digit = calculate_verification_digit(type_code, dni)
41
42 # Formater CUIT/CUIL
43 return f"{type_code}-{str(dni).zfill(8)}-{verification_digit}"
44
45def validate_cuit_cuil(cuit_cuil):
46 # Fjern bindestrek hvis til stede
47 cuit_cuil_clean = cuit_cuil.replace("-", "")
48
49 # Sjekk grunnleggende format
50 if not cuit_cuil_clean.isdigit() or len(cuit_cuil_clean) != 11:
51 return False, "Ugyldig format"
52
53 # Trekk ut deler
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 # Valider type-kode
59 valid_type_codes = [20, 23, 24, 27, 30, 33, 34]
60 if type_code not in valid_type_codes:
61 return False, "Ugyldig type-kode"
62
63 # Beregn og sammenlign verifiseringssiffer
64 calculated_digit = calculate_verification_digit(type_code, dni)
65 if calculated_digit != verification_digit:
66 return False, "Ugyldig verifiseringssiffer"
67
68 return True, "Gyldig CUIT/CUIL"
69
70# Eksempel på bruk
71print(generate_cuit_cuil(20, 12345678)) # Generer for spesifikt DNI
72print(generate_cuit_cuil(27)) # Generer med tilfeldig DNI
73print(validate_cuit_cuil("20-12345678-9")) # Valider en CUIT/CUIL
74JavaScript
1function calculateVerificationDigit(typeCode, dni) {
2 // Konverter til streng og sikre at DNI er 8 sifre med ledende nuller
3 const typeCodeStr = typeCode.toString();
4 const dniStr = dni.toString().padStart(8, '0');
5
6 // Kombiner type-kode og DNI
7 const digits = typeCodeStr + dniStr;
8
9 // Vekter for hver posisjon
10 const weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
11
12 // Beregn sum av produkter
13 let sumProducts = 0;
14 for (let i = 0; i < 10; i++) {
15 sumProducts += parseInt(digits[i]) * weights[i];
16 }
17
18 // Beregn verifiseringssiffer
19 let verificationDigit = 11 - (sumProducts % 11);
20
21 // Spesielle tilfeller
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 // Gyldige type-koder
33 const validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
34
35 if (!validTypeCodes.includes(typeCode)) {
36 throw new Error(`Ugyldig type-kode. Må være en av: ${validTypeCodes.join(', ')}`);
37 }
38
39 // Generer tilfeldig DNI hvis ikke oppgitt
40 if (dni === undefined) {
41 dni = Math.floor(Math.random() * 90000000) + 10000000;
42 }
43
44 // Beregn verifiseringssiffer
45 const verificationDigit = calculateVerificationDigit(typeCode, dni);
46
47 // Formater CUIT/CUIL
48 return `${typeCode}-${dni.toString().padStart(8, '0')}-${verificationDigit}`;
49}
50
51function validateCuitCuil(cuitCuil) {
52 // Fjern bindestrek hvis til stede
53 const cuitCuilClean = cuitCuil.replace(/-/g, '');
54
55 // Sjekk grunnleggende format
56 if (!/^\d{11}$/.test(cuitCuilClean)) {
57 return { isValid: false, errorMessage: 'Ugyldig format' };
58 }
59
60 // Trekk ut deler
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 // Valider type-kode
66 const validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
67 if (!validTypeCodes.includes(typeCode)) {
68 return { isValid: false, errorMessage: 'Ugyldig type-kode' };
69 }
70
71 // Beregn og sammenlign verifiseringssiffer
72 const calculatedDigit = calculateVerificationDigit(typeCode, dni);
73 if (calculatedDigit !== verificationDigit) {
74 return { isValid: false, errorMessage: 'Ugyldig verifiseringssiffer' };
75 }
76
77 return { isValid: true };
78}
79
80// Eksempel på bruk
81console.log(generateCuitCuil(20, 12345678)); // Generer for spesifikt DNI
82console.log(generateCuitCuil(27)); // Generer med tilfeldig DNI
83console.log(validateCuitCuil("20-12345678-9")); // Valider en 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 // Konverter til streng og sikre at DNI er 8 sifre med ledende nuller
11 String typeCodeStr = String.valueOf(typeCode);
12 String dniStr = String.format("%08d", dni);
13
14 // Kombiner type-kode og DNI
15 String digits = typeCodeStr + dniStr;
16
17 // Beregn sum av produkter
18 int sumProducts = 0;
19 for (int i = 0; i < 10; i++) {
20 sumProducts += Character.getNumericValue(digits.charAt(i)) * WEIGHTS[i];
21 }
22
23 // Beregn verifiseringssiffer
24 int verificationDigit = 11 - (sumProducts % 11);
25
26 // Spesielle tilfeller
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("Ugyldig type-kode. Må være en av: " + VALID_TYPE_CODES);
39 }
40
41 // Generer tilfeldig DNI hvis ikke oppgitt
42 if (dni == null) {
43 Random random = new Random();
44 dni = 10000000 + random.nextInt(90000000);
45 }
46
47 // Beregn verifiseringssiffer
48 int verificationDigit = calculateVerificationDigit(typeCode, dni);
49
50 // Formater CUIT/CUIL
51 return String.format("%d-%08d-%d", typeCode, dni, verificationDigit);
52 }
53
54 public static ValidationResult validateCuitCuil(String cuitCuil) {
55 // Fjern bindestrek hvis til stede
56 String cuitCuilClean = cuitCuil.replace("-", "");
57
58 // Sjekk grunnleggende format
59 if (!cuitCuilClean.matches("\\d{11}")) {
60 return new ValidationResult(false, "Ugyldig format");
61 }
62
63 // Trekk ut deler
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 // Valider type-kode
69 if (!VALID_TYPE_CODES.contains(typeCode)) {
70 return new ValidationResult(false, "Ugyldig type-kode");
71 }
72
73 // Beregn og sammenlign verifiseringssiffer
74 int calculatedDigit = calculateVerificationDigit(typeCode, dni);
75 if (calculatedDigit != verificationDigit) {
76 return new ValidationResult(false, "Ugyldig verifiseringssiffer");
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 // Eksempel på bruk
102 System.out.println(generateCuitCuil(20, 12345678)); // Generer for spesifikt DNI
103 System.out.println(generateCuitCuil(27, null)); // Generer med tilfeldig DNI
104 System.out.println(validateCuitCuil("20-12345678-9").isValid()); // Valider en CUIT/CUIL
105 }
106}
107PHP
<?php function calculateVerificationDigit($typeCode, $dni) { // Konverter til streng og sikre at DNI er 8 sifre med ledende nuller $typeCodeStr = (string)$typeCode; $dniStr = str_pad((string)$dni, 8, '0', STR_PAD_LEFT); // Kombiner type-kode og DNI $digits = $typeCodeStr . $dniStr; // Vekter for hver posisjon $weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]; // Beregn sum av produkter $sumProducts = 0; for ($i = 0; $i < 10; $i++) { $sumProducts += (int)$digits[$i] * $weights[$i]; } // Beregn verifiseringssiffer $verificationDigit = 11 - ($sumProducts % 11); // Spesielle tilfeller if ($verificationDigit == 11) { $verificationDigit = 0; } else if ($verificationDigit == 10) { $verificationDigit = 9; } return $verificationDigit; } function generateCuitCuil($typeCode, $dni = null) { // Gyldige type-koder $validTypeCodes = [20, 23, 24, 27, 30, 33, 34]; if (!in_array($typeCode, $validTypeCodes)) { throw new Exception("Ugyldig type-kode. Må være en av: " . implode(', ', $validTypeCodes)); } // Generer tilfeldig DNI hvis ikke oppgitt if ($dni === null) { $dni = rand(10000000, 99999999); } // Beregn verifiseringssiffer $verificationDigit = calculateVerificationDigit($typeCode, $dni); // Formater CUIT/CUIL return sprintf("%d-%08d-%d", $typeCode, $dni, $verificationDigit); } function validateCuitCuil($cuitCuil) { // Fjern bindestrek hvis til stede $cuitCuilClean = str_replace('-', '', $cuitCuil); // Sjekk grunnleggende format if (!preg_match('/^\d{11}$/', $cuitCuilClean)) { return ['isValid' => false, 'errorMessage' => 'Ugyldig format']; } // Trekk ut deler $typeCode = (int)substr($cuitCuilClean, 0, 2); $dni = (int)substr($cuitCuilClean, 2, 8); $verificationDigit = (int)substr($cuitCuilClean, 10, 1); // Valider type-kode $validTypeCodes = [20, 23, 24, 27, 30, 33, 34]; if (!in_array($typeCode, $validTypeCodes)) { return ['isValid' => false, 'errorMessage' => 'Ugyldig type-kode']; } // Beregn og sammenlign verifiseringssiffer $calculatedDigit = calculateVerificationDigit($typeCode, $dni); if ($calculatedDigit !== ## Ofte stilte spørsmål ### Hva er forskjellen mellom CUIT og CUIL? Her er den praktiske forskjellen: **CUIT** (Clave Única de Identificación Tributaria) identifiserer skattytere—både enkeltpersoner og bedrifter som sender inn skatt til AFIP. **CUIL** (Clave Única de Identificación Laboral) identifiserer arbeidere i trygdesystemet for sysselsetting og pensjon. I praksis har mange enkeltpersoner både en CUIL (fra deres første jobb) og kan senere få en CUIT (hvis de blir selvstendig næringsdrivende eller starter en bedrift). Tallene bruker identisk formatering og beregningsregler, så fra et valideringsstandpunkt behandler du dem på samme måte. Forskjellen er viktig for administrative formål: lønnssystemer arbeider vanligvis med CUIL, mens fakturerings- og skattesystemer bruker CUIT. ### Hvilke typekoder brukes for enkeltpersoner og hvilke for selskaper? For enkeltpersoner: - 20, 23, 24: Mannlige enkeltpersoner (CUIL) - 27: Kvinnelige enkeltpersoner (CUIL) For selskaper og organisasjoner: - 30: Selskaper (CUIT) - 33: Sivile foreninger (CUIT) - 34: Stiftelser (CUIT) ### Hvordan beregnes kontrollsifferet? Algoritmen bruker vektet multiplikasjon: ta hver av de første 10 sifrene, multipliser med vektene **5, 4, 3, 2, 7, 6, 5, 4, 3, 2**, summer produktene, så beregn 11 minus (sum modulo 11). To grensetilfeller forvirrer folk: når beregningen gir 11, bruk 0 som kontrollsifre; når den gir 10, bruk 9. Disse spesialtilfellene eksisterer fordi kontrollsifferet må være et enkelt siffer (0-9). Dette er en modulo-11 kontrollsifre-algoritme, lik den som brukes i ISBN-10-koder og andre identifikasjonssystemer over hele verden. ### Kan jeg bruke dette verktøyet til å generere ekte, offisielle CUIT/CUIL-nummer? Nei—dette verktøyet genererer matematisk gyldige testdata, men tallene er ikke offisielt registrert hos AFIP. Tenk på det som å generere et gyldig kredittkort ved hjelp av Luhn-algoritmen: det passerer formatvalidering, men er ikke koblet til en ekte konto. For offisiell CUIT/CUIL-registrering må enkeltpersoner besøke AFIP med sin DNI, mens bedrifter må fullføre prosedyrer for foretaksregistrering. Verktøyet er strengt for utvikling, testing og opplæringsbruk der du trenger gyldige data som ikke vil komme i konflikt med ekte identifikasjonsnummer. ### Hvorfor mislykkes CUIT/CUIL-validering selv om formatet ser riktig ut? Når validering mislykkes til tross for riktig formatering, sjekk disse vanlige synderne: 1. **Ugyldig typekode**: Kun 20, 23, 24, 27, 30, 33, 34 er gyldige. Bruk av 21, 25 eller andre tall vil feile. 2. **Feil kontrollsifre**: Det siste sifferet må stemme med algoritmens beregning. Selv å endre ett siffer i DNI-delen krever å beregne kontrollsifferet på nytt. 3. **Formatproblemer**: Må være nøyaktig 11 sifre (XX-XXXXXXXX-X). Vær oppmerksom på ekstra mellomrom eller manglende ledende nuller. 4. **Skjulte tegn**: Kopiering fra PDF-er eller nettsider kan innføre usynlige Unicode-tegn som ødelegger validering. Et raskt feilsøkingstips: fjern det siste sifferet og beregn det manuelt. Hvis det ikke stemmer, er det der problemet ligger. ### Er bindestrek påkrevd i CUIT/CUIL-nummer? Bindestrek er kun for visningsformatering—den er ikke en del av selve nummeret for beregningsformål. Når du ser **20-12345678-9**, bryr algoritmen seg bare om de 11 sifrene: **20123456789**. De fleste valideringsimplementasjoner fjerner bindestrek før behandling, noe som er grunnen til at vårt verktøy aksepterer både **20-12345678-9** og **20123456789**. I APIer og databaser vil du vanligvis lagre den ubundne versjonen og legge til bindestrek kun ved visning for brukere. Denne tilnærmingen forhindrer at formateringsinkonsistenser forårsaker valideringsfeil. ### Kan et CUIT/CUIL-nummer ha færre enn 8 sifre i DNI-delen? DNI-delen må alltid være nøyaktig 8 sifre—ingen unntak. Hvis noen faktiske DNI har færre sifre (som skjer med eldre, lavere nummererte DNI-er), fyller du på med ledende nuller. For eksempel blir DNI **1234567** til **01234567** i CUIT/CUIL-strukturen. Dette er en hyppig kilde til feil ved konvertering mellom DNI- og CUIT/CUIL-formater. Jeg har sett systemer mislykkes med validering fordi de glemte å fylle på, og behandlet **1234567** som et 7-sifret tall i stedet for **01234567**. Bruk alltid nullpåfyllingsfunksjoner i koden din i stedet for enkel strengsammensetting. ### Hvordan kan jeg verifisere om en CUIT/CUIL er offisielt registrert i Argentina? Vårt verktøy validerer matematisk riktighet—format, typekode og kontrollsifre. Men det kan ikke fortelle deg om nummeret faktisk er registrert hos AFIP eller tilhører en ekte person eller bedrift. For offisiell verifisering, bruk [AFIP's webtjenester](https://www.afip.gob.ar/) eller deres "Constancia de Inscripción" oppslagningstjeneste. AFIP tilbyr APIer for automatisk verifisering, selv om du må registrere deg som utvikler og autentisere deg. I produksjonsmiljøer implementerer du begge lag: kjør først algoritmisk validering (rask, fanger opp skrivefeil og formatfeil), deretter verifiser mot AFIP's database (saktere, men bekrefter at nummeret er ekte og aktivt). ### Kan jeg bruke dette verktøyet i min kommersielle applikasjon? Ja—CUIT/CUIL-valideringsalgoritmen er en offentlig standard definert av AFIP, så du kan fritt implementere den i kommersiell programvare. Kodeksemplene her er ment som referanseimplementasjoner. For produksjonsbruk, vurder disse beste praksiser: implementer riktig feilhåndtering for grensetilfeller, legg til logging for feilsøking av valideringsfeil, valider mot AFIP's offisielle database (ikke bare algoritmisk validering), og hold implementasjonen oppdatert hvis AFIP endrer reglene (selv om den nåværende algoritmen har vært stabil i årevis). ### Lagrer verktøyet noen av de genererte eller validerte CUIT/CUIL-numrene? Nei—all behandling skjer i nettleseren din (klientsiden). Når du genererer eller validerer en CUIT/CUIL, kjøres beregningen lokalt ved hjelp av JavaScript. Ingenting sendes til våre servere, og vi logger, lagrer eller sporer ingen nummer du legger inn eller genererer. Denne klientsidige tilnærmingen sikrer personvern og betyr også at verktøyet fungerer frakoblet når siden er lastet. Du kan bekrefte dette ved å åpne nettleserens utviklingsverktøy og se på nettverksfanen—du vil se ingen forespørsler sendt ved generering eller validering av nummer. ## Referanser 1. AFIP (Administración Federal de Ingresos Públicos). "CUIT/CUIL/CDI." Offisiell nettside. [https://www.afip.gob.ar/](https://www.afip.gob.ar/) 2. Arbeids-, sysselsettings- og sosialsikkerhetsdepartementet. "CUIL - Unik arbeidsidentifikasjonskode." [https://www.argentina.gob.ar/trabajo](https://www.argentina.gob.ar/trabajo) 3. ANSES (Administración Nacional de la Seguridad Social). "Få min CUIL." [https://www.anses.gob.ar/](https://www.anses.gob.ar/) 4. Offisiell bulletin for Den argentinske republikk. "AFIP generell resolusjon 2854/2010: Prosedyre. Unik skattidentifikasjonskode (C.U.I.T.)." 5. Skattelov for Den argentinske republikk. "Identifikasjon og registrering av skatteytere." --- Enten du bygger et faktureringssystem, tester ansattregistreringsflyter eller lærer om valideringsalgoritmer, tilbyr dette verktøyet CUIT/CUIL-generering og -validering du trenger. Generer testdata som passerer algoritmisk validering, verifiser numre før de når databasen din, eller utforsk hvordan sjekksiffer-algoritmen fungerer i praksis.