CUIT/CUIL-generaattori ja -validaattori | Argentiinalainen verotunnisteen työkalu
Luo kelvollisia argentiinalaisia CUIT/CUIL-testinumeroita tai validoi olemassa olevia. Ilmainen verkkotyökalu kehittäjille, jotka testaavat verotunniste- ja palkanlaskentajärjestelmiä AFIP-yhteensopivalla validoinnilla.
CUIT/CUIL-tunnuksen Luoja
Syötä 8-numeroinen DNI-numero tai käytä satunnaista generaattoria
Käytetään satunnaisesti luotua DNI:tä
Dokumentaatio
Argentiinalainen CUIT/CUIL-generaattori ja -validaattori
Johdanto
Argentiinan vero- ja työjärjestelmässä törmäät jatkuvasti kahteen kriittiseen tunnistimeen: CUIT (Clave Única de Identificación Tributaria) ja CUIL (Clave Única de Identificación Laboral). Ajattele CUIT:ia verotunnuksena yrityksille ja henkilöille, jotka maksavat veroja, kun taas CUIL tunnistaa työntekijät sosiaaliturvalaitoksen järjestelmässä. Molemmat käyttävät samaa 11-merkkistä muotoa ja tarkistusalgoritmia, mikä tekee näitä numeroita käsittelevien sovellusten testaamisen erityisen tärkeäksi.
Kun kehität ohjelmistoa Argentiinan markkinoille, tarvitset kelvollisia testausaineistoja. Tähän tämä työkalu tulee avuksi. Voit luoda matemaattisesti oikeita CUIT/CUIL-numeroita testausta varten käyttämättä todellisia henkilötietoja tai vahvistaa olemassa olevia numeroita varmistaaksesi, että ne noudattavat AFIP:n virallista algoritmia. Erityisen hyödyllistä on, että työkalu hoitaa sekä luomispuolen (luo tarvittaessa kelvollisia numeroita) että vahvistuspuolen (havaitsee muotovirheet, virheelliset tyyppikoodit ja väärät tarkistusnumerot ennen kuin ne aiheuttavat ongelmia tuotannossa).
CUIT/CUIL-rakenne ja laskenta
Rakenteen ymmärtäminen
Kelvollinen CUIT/CUIL-numero koostuu 11 numerosta, jotka tyypillisesti näytetään muodossa XX-XXXXXXXX-X. Näin se jakautuu:
-
Tyyppikoodi (ensimmäiset 2 numeroa): Tunnistaa yksikön tyypin
- 20, 23, 24: Miespuoliset henkilöt (CUIL)
- 27: Naispuoliset henkilöt (CUIL)
- 30, 33, 34: Yritykset ja organisaatiot (CUIT)
-
DNI-numero (keskimmäiset 8 numeroa): Henkilöille tämä on heidän kansallinen henkilötunnuksensa (DNI). Yleinen sudenkuoppa: jos varsinainen DNI on alle 8 numeroa, se täytyy täyttää etunolilla. Esimerkiksi DNI 1234567 muuttuu CUIT/CUIL:ssa muotoon 01234567. Yritykset saavat sen sijaan yksilöllisen määritetyn numeron.
-
Tarkistusnumero (viimeinen numero): Tämä tarkistusnumero vahvistaa koko numeron käyttäen painotettua algoritmia. Jos tämä numero ei täsmää laskelmaan, koko CUIT/CUIL on virheellinen - asia, joka usein yllättää kehittäjät heidän manuaalisesti luodessaan testidataa.
Tarkistusnumeron laskenta
Tarkistusnumero käyttää modulo-11 painotettua algoritmia. Näin se toimii:
- Ota CUIT/CUIL:n ensimmäiset 10 numeroa (tyyppikoodi + DNI)
- Kerro jokainen numero vastaavalla painokertoimella: 5, 4, 3, 2, 7, 6, 5, 4, 3, 2
- Laske tuotteiden summa
- Laske: 11 miinus (summa modulo 11)
- Käsittele erikoistapaukset: jos tulos on 11, käytä 0; jos se on 10, käytä 9
Eniten hämmennystä aiheuttavat vaiheessa 5 olevat erikoistapaukset. Testattaessa saat joskus tulokseksi 10 tai 11, ja näiden muuntamisen unohtaminen 9:ksi ja 0:ksi aiheuttaa validointivirheitä, joita voi olla vaikea debugata, ellei tiedä tätä sääntöä.
Matemaattisesti tämä voidaan ilmaista seuraavasti:
Missä:
- on tarkistusnumero
- on ensimmäisen 10 numeron :s numero
- on vastaava painokerroin sarjasta [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
- Erikoistapaukset: jos niin , jos niin
Vaiheittainen opas
Generaattorin käyttö
-
Valitse "Generaattori"-välilehti työkalun käyttöliittymän yläosasta.
-
Valitse Tyyppikoodi pudotusvalikosta:
- 20: Mies (CUIL)
- 23: Yritys (CUIT)
- 24: Väliaikainen yritys (CUIT)
- 27: Nainen (CUIL)
- 30: Yhtiö (CUIT)
- 33: Kansalaisjärjestö (CUIT)
- 34: Säätiö (CUIT)
-
Syötä DNI-numero (valinnainen):
- Syötä 8-numeroinen DNI-numero annettuun kenttään
- Jos jätetään tyhjäksi, työkalu käyttää satunnaisesti generoitua DNI:tä
- Jos syötät alle 8 numeroa, järjestelmä täyttää etunollilla
-
Generoi satunnainen DNI (valinnainen):
- Napsauta "Satunnainen"-painiketta luodaksesi satunnaisen 8-numeroisen DNI-numeron
-
Näytä luotu CUIT/CUIL:
- Työkalu näyttää automaattisesti kelvollisen CUIT/CUIL:in syötteidesi perusteella
- Muoto on XX-XXXXXXXX-X oikealla tarkistenumerolla
-
Kopioi tulos:
- Napsauta kopiointikuvaketta kopioidaksesi luodun CUIT/CUIL:in leikepöydälle
- Vahvistusviesti näytetään, kun kopiointi on onnistunut
Validaattorin käyttö
-
Valitse "Validaattori"-välilehti työkalun käyttöliittymän yläosasta.
-
Syötä validoitava CUIT/CUIL:
- Syötä CUIT/CUIL muodossa XX-XXXXXXXX-X
- Työkalu muotoilee syötteesi automaattisesti välimerkeillä sitä kirjoitettaessa
- Voit myös syöttää numeron ilman välimerkkejä (XXXXXXXXXXX)
-
Napsauta "Validoi"-painiketta:
- Työkalu tarkistaa muodon, tyyppikoodin ja tarkistenumeron
-
Näytä validointitulos:
- Kelvollisille CUIT/CUIL-numeroille näytetään vihreä onnistumisviesti
- Virheellisille numeroille näytetään punainen virheviesti, joka selittää ongelman:
- Virheellinen muoto (oltava XX-XXXXXXXX-X)
- Virheellinen tyyppikoodi (oltava jokin: 20, 23, 24, 27, 30, 33, 34)
- Virheellinen tarkistenumero
-
Lisätiedot:
- Kelvollisille numeroille työkalu näyttää komponenttien erittelyn:
- Tyyppikoodin ja sen merkityksen
- DNI-numeron
- Tarkistenumeron
- Kelvollisille numeroille työkalu näyttää komponenttien erittelyn:
Yleiset virheet ja parhaat käytännöt
Kun työskentelet CUIT/CUIL-validoinnin parissa sovelluksissasi, varo näitä yleisiä sudenkuoppia:
Nollapehmentämiseen liittyvät ongelmat: Yleisin kohtaamani virhe koskee DNI-numeroita, joissa on etunollia. Kun joku syöttää DNI:n "1234567", koodisi tarvitsee käsitellä sen muodossa "01234567" CUIT/CUIL-rakenteessa. Monet toteutukset muuntavat sen kokonaisluvuksi käsittelyä varten, mikä poistaa etunollat. Käytä sen sijaan merkkijonooperaatioita asianmukaisella pehmennyksellä.
Tyyppikoodin sekaannus: Kaikki kaksinumeroiset koodit eivät ole kelvollisia. Vain 20, 23, 24, 27, 30, 33, 34 toimivat. Olen nähnyt järjestelmiä, jotka hyväksyvät minkä tahansa kaksinumeroisen etuliitteen, mikä johtaa "valideilta näyttäviin" numeroihin kuten 21-12345678-X, jotka eivät läpäise AFIP-validointia. Tarkista aina tyyppikoodin kelpoisuus ennen tarkistusnumeron laskemista.
Sukupuolioletusten virheet: Tyyppikoodit 20 (mies) ja 27 (nainen) eivät ole vaihdettavissa. Jos luot CUILeja automaattisesti demografisten tietojen perusteella, varmista, että tyyppikoodisi vastaa sukupuolta, joka on rekisteröity RENAPERiin (Argentiinan kansallinen rekisteri). Ristiriitaisuudet johtavat hylkäämiseen, kun henkilöt yrittävät käyttää näitä numeroita valtion palveluissa.
Väliviivan käsittely: Jotkin toteutukset vaativat väliviivoja, toiset hylkäävät ne. Paras käytäntö: hyväksy molemmat muodot syöttökentissä (väliviivalla tai ilman), poista väliviivat ennen validointia, tallenna väliviivaton versio tietokantoihin ja lisää väliviivat vain näyttötarkoituksessa.
Puuttuva tarkistus: Algoritmin validointi havaitsee muotovirheet, mutta ei vahvista, että CUIT/CUIL on rekisteröity. Tuotannossa validoi ensin muoto (nopea), sitten tarkista AFIP:n tietokannasta (hitaampi mutta auktoritatiivinen). Tämä kaksivaiheinen lähestymistapa havaitsee kirjoitusvirheet välittömästi samalla varmistaen numeron aitouden.
Reunatapausten testaus: Testaa aina tarkistusnumeroilla 0 ja 9 - nämä ovat seurausta algoritmin erikoistapauksista. Testaa myös DNI:t, jotka alkavat nollilla, varmistaaksesi, että pehmennyslogiikkasi toimii oikein.
Käyttötapaukset ja käytännön sovellukset
Kehitys ja testaus
Ohjelmistokehitys: Kun rakennat sovelluksia Argentiinan markkinoille, tarvitset testidataa, joka läpäisee validoinnin käyttämättä todellisia käyttäjätietoja. Tässä kohtaa tämä tulee kriittiseksi:
- Verkkokauppa-alustat: Maksunvälittäjät ja laskutusjärjestelmät vaativat kelvollisia CUIT/CUIL-numeroita. Kuormitustestauksessa saatat tarvita tuhansia kelvollisia numeroita simuloidaksesi realistisia käyttäjärekisteröintejä.
- Kirjanpito-ohjelmistot: Veroraportointimoduulit varmistavat CUIT/CUIL-muodon ennen lähettämistä AFIP:ille. Näiden validointisääntöjen testaaminen vaatii numeroita, jotka läpäisevät tarkistusnumeron algoritmin.
- HR-hallintajärjestelmät: Palkanmaksu ja sosiaaliturvamaksut riippuvat kelvollisista CUIL-numeroista. Yleinen skenaario: testaat työntekijöiden käyttöönottoprosessia ja tarvitset varmistaa, että virheelliset CUIL-numerot laukaisevat asianmukaiset virheilmoitukset.
- Pankkisovellukset: KYC (Know Your Customer) -prosessit validoivat CUIT/CUIL-numeron osana tilin avaamista. Kokemukseni mukaan reunatapaukset kuten tyyppikoodin ristiriidat usein nousevat esiin integraatiotestauksessa.
Tietokannan täyttö: Kun täytät testikantoja, algoritmisesti kelvollisten CUIT/CUIL-numeroiden käyttö varmistaa, että tietokantarajoitukset ja käynnistimet toimivat odotetulla tavalla. Tämä on erityisen tärkeää testattaessa tietojen siirtoskriptejä tai ETL-prosesseja, jotka validoivat tunnistenumerot.
Lomakkeen validointitestaus: Testaa sekä onnistunut polku että virhetilanteet. Luo kelvollisia numeroita varmistaaksesi onnistuneen lähetyksen, sitten muokkaa tarkistusnumeroa varmistaaksesi, että sekä frontend että backend validointi havaitsee virheen ennen tietokantaan pääsyä.
API-testaus: Integraatiotestien tulee käyttää kelvollisia CUIT/CUIL-numeroita pyynnön kuormassa. Tämä estää väärät negatiiviset tulokset, joissa testit epäonnistuvat virheellisen testidatan vuoksi eikä todellisten API-logiikan vikojen takia.
QA-automaatio: Parametroidut testit hyötyvät dynaamisesta CUIT/CUIL-generoinnista. Sen sijaan, että kovakoodaisit testiarvoiksi, jotka saattavat olla ristiriidassa eri testiajojen välillä, generoi tuoreita kelvollisia numeroita jokaiseen testisuoritukseen.
Koulutukselliset tarkoitukset
Validointialgoritmien oppiminen: CUIT/CUIL-vahvistusalgoritmi osoittaa moduloaritmetiikan ja painotettujen tarkistusnumeroiden käytännön sovelluksen. Sama malli esiintyy muissa tunnistusjärjestelmissä maailmanlaajuisesti—luottokorttinumerot (Luhn-algoritmi), ISBN-koodit ja eurooppalaiset ALV-numerot käyttävät kaikki samankaltaisia painotettuja tarkistussummamenetelmiä. CUIT/CUIL-validoinnin ymmärtäminen tarjoaa näkemyksen siitä, miksi nämä algoritmit ovat olemassa: ne havaitsevat litterointivirheet kuten vaihdetut numerot tai yhden numeron virheet.
Tietojen validoinnin opettaminen: Kun koulutat nuoria kehittäjiä syötteen validoinnissa, CUIT/CUIL-järjestelmä tarjoaa todellisen maailman esimerkin, joka on monimutkaisempi kuin sähköpostin validointi mutta yksinkertaisempi kuin kryptografinen vahvistus. Se osoittaa syvyyssuuntaisen puolustuksen periaatteen: muotovalidointi (11 numeroa), liiketoimintasääntöjen validointi (kelvolliset tyyppikoodit) ja algoritminen validointi (tarkistusnumero).
Kansainvälinen liiketoiminnan kehittäminen: Jos rakennat järjestelmiä Latinalaisen Amerikan markkinoille, CUIT/CUIL:n ymmärtäminen auttaa sinua käsittämään vastaavia järjestelmiä naapurimaissa. Brasiliassa on CPF/CNPJ, Chilessä RUT ja Uruguayssa RUT—kaikki käyttävät tarkistusnumeroalgoritmeja. Täällä oppimasi mallit siirtyvät näihin järjestelmiin.
Vaihtoehdot ja tuotantoharkinta
Vaikka tämä työkalu toimii hyvin kehitys- ja testauskäytössä, tuotantoympäristöillä on erilaiset vaatimukset:
Virallinen valtiollinen validointi: Reaaliaikaisissa sovelluksissa pelkkä algoritminen validointi ei riitä—sinun täytyy varmistaa, että CUIT/CUIL on todella rekisteröity AFIP (Administración Federal de Ingresos Públicos):ssa. AFIP tarjoaa verkkopalvelut reaaliaikaiseen validointiin, joskin sinun täytyy rekisteröityä ja todentaa päästäksesi niihin. Haaste on siinä, että numero voi olla matemaattisesti kelvollinen mutta ei virallisesti määritelty, joten toteuta aina molemmat validointitasot tuotannossa.
Kirjastot ja paketit: Jos integroit CUIT/CUIL-validoinnin koodipohjaan, harkitse näitä vakiintuneita kirjastoja oman ratkaisun kehittämisen sijaan:
- JavaScript:
validar-cuitnpm:ssä hoitaa validoinnin ja muotoilun - PHP:
afip-php-kirjasto tarjoaa sekä validoinnin että AFIP-verkkopalveluintegraation - Python:
py-cuitPyPI:ssä toteuttaa täyden algoritmin
Ylläpidettyjen kirjastojen käyttö vähentää toteutusvirheiden riskiä ja sisältää usein reunatapaukset, jotka itse toteutetussa koodissa saattaisivat jäädä huomioimatta.
Manuaalinen laskenta: Oppimis- tai virheenkorjaustarkoituksiin algoritmin läpikäyminen käsin auttaa vahvistamaan ymmärrystä. Ota laskin ja näytenumero, sitten seuraa painotettua kertolaskuprosessia askel askeleelta.
Yritysvalidointipalvelut: Laajamittaiset sovellukset saattavat hyötyä kolmannen osapuolen validointirajapinnoista, jotka tarkistavat muodon lisäksi myös ristiviittaavat kaupalliset tietokannat. Nämä palvelut voivat merkitä passiiviset yritykset, tunnistaa sanktioitujen yksiköiden tiedot tai tarjota lisätietoja CUIT/CUIL-haltijasta.
CUIT/CUIL-järjestelmän historia
CUIT/CUIL-tunnistusjärjestelmä Argentiinassa on kehittynyt merkittävästi perustamisestaan lähtien:
Alkuperä ja käyttöönotto
CUIT (Clave Única de Identificación Tributaria) otettiin ensin käyttöön Argentiinassa 1970-luvulla osana veronkeruujärjestelmän modernisointipyrkimyksiä. Julkisen tuoton liittovaltion hallinto (AFIP) otti käyttöön tämän ainutlaatuisen tunnisteen veronmaksajien tehokkaamman seurannan ja veronkierron vähentämisen helpottamiseksi.
CUIL (Clave Única de Identificación Laboral) otettiin myöhemmin käyttöön erityisesti työntekijöiden tunnistamiseen sosiaaliturvan järjestelmässä, luoden eron vero- ja työllisyystunnisteiden välille samalla säilyttäen yhdenmukaisen muodon.
Kehitys ja digitalisointi
1990-luvulla, kun Argentiina kävi läpi merkittäviä taloudellisia uudistuksia, CUIT/CUIL-järjestelmästä tuli yhä tärkeämpi taloudellisen toiminnan seuraamisessa. Järjestelmää digitalisoitiin edelleen ja online-todennusjärjestelmiä otettiin käyttöön.
2000-luvun alussa CUIT/CUIL-järjestelmä integroitiin erilaisiin digitaalisiin hallinnon palveluihin tehden siitä keskeisen osan Argentiinan sähköisen hallinnon aloitteita. Tänä aikana myös todennusalgoritmi ja muoto standardisoitiin vastaamaan nykyään käytössä olevaa versiota.
Viimeaikaiset kehitykset
Viime vuosina AFIP on parantanut CUIT/CUIL-numeroiden turvallisuutta ja todennusprosesseja ottamalla käyttöön kehittyneempiä validointijärjestelmiä ja integroimalla niitä muihin hallinnon tietokantoihin. Järjestelmällä on nyt keskeinen rooli Argentiinan pyrkimyksissä torjua veronkiertoa ja muodollistaa taloutta.
Tänään CUIT/CUIL:iä käytetään vero- ja työllistymistarkoitusten lisäksi laajasti eri toiminnoissa, kuten pankkitoiminnassa, kiinteistökaupoissa, yleishyödyllisissä palveluissa ja verkko-ostoissa, tehden siitä välttämättömän tunnisteen sekä henkilöille että yrityksille, jotka toimivat Argentiinassa.
Toteutuksen huomioon ottaminen
Kun toteutat CUIT/CUIL-validointia omissa järjestelmissäsi, ota huomioon nämä tekniset näkökohdat:
Algoritmin vakaus: Nykyinen CUIT/CUIL-tarkistusalgoritmi on pysynyt muuttumattomana sen standardoinnista 1990-luvulla lähtien. AFIPin teknisen dokumentaation mukaan modulo-11-painotettu tarkistusnumeroalgoritmi on kodifioitu Resolución General 2854/2010:ssä ja myöhemmissä säädöksissä. Tämä vakaus tarkoittaa, että toteutukset harvoin tarvitsevat päivityksiä, mutta sinun tulee seurata AFIPin tiedotteita mahdollisista sääntelymuutoksista.
Suorituskyvyn optimointi: Tarkistusalgoritmi on laskennallisesti edullinen—vain 10 kertolaskua, yksi yhteenlasku ja yksi modulo-operaatio. Korkeaa läpimenoa käsitteleville järjestelmille, jotka käsittelevät tuhansia tarkistuksia sekunnissa, pullonkaula on tyypillisesti verkkoviive tarkistettaessa AFIPin tietokannasta, ei algoritmi itse. Harkitse AFIPin tarkistustulosten välimuistittamista sopivilla TTL:illä (tyypillisesti 24 tuntia) tasapainottaen tuoreutta ja suorituskykyä.
Merkkikoodaus: Käsitellessäsi CUIT/CUIL-tietoja ulkoisista lähteistä (PDF:t, skannatut asiakirjat, web-scraping), kiinnitä huomiota merkkikoodausongelmiin. Yhdysmerkki saattaa näkyä em-viivana (U+2014), en-viivana (U+2013) tai miinusmerkkinä (U+2212) tavallisen yhdysmerkin (U+002D) sijaan. Normalisoi nämä ennen tarkistusta välttääksesi vääriä negatiivisia tuloksia.
Kansainvälistäminen: Jos sovelluksesi palvelee useita Latinalaisen Amerikan markkinoita, huomaa, että Argentiinan CUIT/CUIL käyttää modulo-11:tä tietyillä painoarvoilla, kun taas Chilen RUT käyttää modulo-11:tä eri painoarvoilla, ja Brasilian CPF/CNPJ käyttää modulo-11:tä vielä toisenlaisella kuviolla. Älä oleta, että algoritmit ovat identtisiä—jokaisella maan järjestelmällä on omat sääntönsä. Laajemman ymmärryksen saamiseksi tarkistusnumeroalgoritmeista, katso ISO/IEC 7064 -standardi, joka muodollistaa erilaiset modulo-pohjaiset tarkistuskaavat.
Tietokantatalletus: Tallenna CUIT/CUIL-numerot ilman yhdysmerkkejä kiinteänpituisina CHAR(11):nä tai BIGINT:nä, jos tietokantasi tukee 11-numeroisia kokonaislukuja ilman tarkkuuden menetystä. Lisää tarkistusrajoite, joka vahvistaa tarkistusnumeron tietokantatasolla suojana vioittuneita tietoja vastaan. Luo indeksit tälle kentälle tehokkaita hakuja varten käyttäjien etsiessä CUIT/CUIL:n perusteella.
Koodiesimerkit
Python
1def calculate_verification_digit(type_code, dni):
2 # Muunna merkkijonoksi ja varmista, että DNI on 8 numeroa etunollilla
3 type_code_str = str(type_code)
4 dni_str = str(dni).zfill(8)
5
6 # Yhdistä tyyppikoodi ja DNI
7 digits = type_code_str + dni_str
8
9 # Painokertoimet jokaiselle positiolle
10 weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
11
12 # Laske tuotteiden summa
13 sum_products = sum(int(digits[i]) * weights[i] for i in range(10))
14
15 # Laske tarkistenumero
16 verification_digit = 11 - (sum_products % 11)
17
18 # Erikoistapaukset
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 # Kelvolliset tyyppikoodit
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"Virheellinen tyyppikoodi. Täytyy olla jokin seuraavista: {valid_type_codes}")
34
35 # Generoi satunnainen DNI, jos ei ole annettu
36 if dni is None:
37 dni = random.randint(10000000, 99999999)
38
39 # Laske tarkistenumero
40 verification_digit = calculate_verification_digit(type_code, dni)
41
42 # Muotoile CUIT/CUIL
43 return f"{type_code}-{str(dni).zfill(8)}-{verification_digit}"
44
45def validate_cuit_cuil(cuit_cuil):
46 # Poista väliviivat, jos niitä on
47 cuit_cuil_clean = cuit_cuil.replace("-", "")
48
49 # Tarkista perusmuoto
50 if not cuit_cuil_clean.isdigit() or len(cuit_cuil_clean) != 11:
51 return False, "Virheellinen muoto"
52
53 # Pura osat
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 # Vahvista tyyppikoodi
59 valid_type_codes = [20, 23, 24, 27, 30, 33, 34]
60 if type_code not in valid_type_codes:
61 return False, "Virheellinen tyyppikoodi"
62
63 # Laske ja vertaa tarkistenumeroa
64 calculated_digit = calculate_verification_digit(type_code, dni)
65 if calculated_digit != verification_digit:
66 return False, "Virheellinen tarkistenumero"
67
68 return True, "Kelvollinen CUIT/CUIL"
69
70# Käyttöesimerkki
71print(generate_cuit_cuil(20, 12345678)) # Generoi tietylle DNI:lle
72print(generate_cuit_cuil(27)) # Generoi satunnaisella DNI:llä
73print(validate_cuit_cuil("20-12345678-9")) # Vahvista CUIT/CUIL
74JavaScript
1function calculateVerificationDigit(typeCode, dni) {
2 // Muunna merkkijonoksi ja varmista, että DNI on 8 numeroa etunollilla
3 const typeCodeStr = typeCode.toString();
4 const dniStr = dni.toString().padStart(8, '0');
5
6 // Yhdistä tyyppikoodi ja DNI
7 const digits = typeCodeStr + dniStr;
8
9 // Painokertoimet jokaiselle positiolle
10 const weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
11
12 // Laske tuotteiden summa
13 let sumProducts = 0;
14 for (let i = 0; i < 10; i++) {
15 sumProducts += parseInt(digits[i]) * weights[i];
16 }
17
18 // Laske tarkistenumero
19 let verificationDigit = 11 - (sumProducts % 11);
20
21 // Erikoistapaukset
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 // Kelvolliset tyyppikoodit
33 const validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
34
35 if (!validTypeCodes.includes(typeCode)) {
36 throw new Error(`Virheellinen tyyppikoodi. Täytyy olla jokin seuraavista: ${validTypeCodes.join(', ')}`);
37 }
38
39 // Generoi satunnainen DNI, jos ei ole annettu
40 if (dni === undefined) {
41 dni = Math.floor(Math.random() * 90000000) + 10000000;
42 }
43
44 // Laske tarkistenumero
45 const verificationDigit = calculateVerificationDigit(typeCode, dni);
46
47 // Muotoile CUIT/CUIL
48 return `${typeCode}-${dni.toString().padStart(8, '0')}-${verificationDigit}`;
49}
50
51function validateCuitCuil(cuitCuil) {
52 // Poista väliviivat, jos niitä on
53 const cuitCuilClean = cuitCuil.replace(/-/g, '');
54
55 // Tarkista perusmuoto
56 if (!/^\d{11}$/.test(cuitCuilClean)) {
57 return { isValid: false, errorMessage: 'Virheellinen muoto' };
58 }
59
60 // Pura osat
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 // Vahvista tyyppikoodi
66 const validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
67 if (!validTypeCodes.includes(typeCode)) {
68 return { isValid: false, errorMessage: 'Virheellinen tyyppikoodi' };
69 }
70
71 // Laske ja vertaa tarkistenumeroa
72 const calculatedDigit = calculateVerificationDigit(typeCode, dni);
73 if (calculatedDigit !== verificationDigit) {
74 return { isValid: false, errorMessage: 'Virheellinen tarkistenumero' };
75 }
76
77 return { isValid: true };
78}
79
80// Käyttöesimerkki
81console.log(generateCuitCuil(20, 12345678)); // Generoi tietylle DNI:lle
82console.log(generateCuitCuil(27)); // Generoi satunnaisella DNI:llä
83console.log(validateCuitCuil("20-12345678-9")); // Vahvista 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 // Muunna merkkijonoksi ja varmista, että DNI on 8 numeroa etunollilla
11 String typeCodeStr = String.valueOf(typeCode);
12 String dniStr = String.format("%08d", dni);
13
14 // Yhdistä tyyppikoodi ja DNI
15 String digits = typeCodeStr + dniStr;
16
17 // Laske tuotteiden summa
18 int sumProducts = 0;
19 for (int i = 0; i < 10; i++) {
20 sumProducts += Character.getNumericValue(digits.charAt(i)) * WEIGHTS[i];
21 }
22
23 // Laske tarkistenumero
24 int verificationDigit = 11 - (sumProducts % 11);
25
26 // Erikoistapaukset
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("Virheellinen tyyppikoodi. Täytyy olla jokin seuraavista: " + VALID_TYPE_CODES);
39 }
40
41 // Generoi satunnainen DNI, jos ei ole annettu
42 if (dni == null) {
43 Random random = new Random();
44 dni = 10000000 + random.nextInt(90000000);
45 }
46
47 // Laske tarkistenumero
48 int verificationDigit = calculateVerificationDigit(typeCode, dni);
49
50 // Muotoile CUIT/CUIL
51 return String.format("%d-%08d-%d", typeCode, dni, verificationDigit);
52 }
53
54 public static ValidationResult validateCuitCuil(String cuitCuil) {
55 // Poista väliviivat, jos niitä on
56 String cuitCuilClean = cuitCuil.replace("-", "");
57
58 // Tarkista perusmuoto
59 if (!cuitCuilClean.matches("\\d{11}")) {
60 return new ValidationResult(false, "Virheellinen muoto");
61 }
62
63 // Pura osat
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 // Vahvista tyyppikoodi
69 if (!VALID_TYPE_CODES.contains(typeCode)) {
70 return new ValidationResult(false, "Virheellinen tyyppikoodi");
71 }
72
73 // Laske ja vertaa tarkistenumeroa
74 int calculatedDigit = calculateVerificationDigit(typeCode, dni);
75 if (calculatedDigit != verificationDigit) {
76 return new ValidationResult(false, "Virheellinen tarkistenumero");
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 // Käyttöesimerkki
102 System.out.println(generateCuitCuil(20, 12345678)); // Generoi tietylle DNI:lle
103 System.out.println(generateCuitCuil(27, null)); // Generoi satunnaisella DNI:llä
104 System.out.println(validateCuitCuil("20-12345678-9").isValid()); // Vahvista CUIT/CUIL
105 }
106}
107PHP
<?php function calculateVerificationDigit($typeCode, $dni) { // Muunna merkkijonoksi ja varmista, että DNI on 8 numeroa etunollilla $typeCodeStr = (string)$typeCode; $dniStr = str_pad((string)$dni, 8, '0', STR_PAD_LEFT); // Yhdistä tyyppikoodi ja DNI $digits = $typeCodeStr . $dniStr; // Painokertoimet jokaiselle positiolle $weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]; // Laske tuotteiden summa $sumProducts = 0; for ($i = 0; $i < 10; $i++) { $sumProducts += (int)$digits[$i] * $weights[$i]; } // Laske tarkistenumero $verificationDigit = 11 - ($sumProducts % 11); // Erikoistapaukset if ($verificationDigit == 11) { $verificationDigit = 0; } else if ($verificationDigit == 10) { $verificationDigit = 9; } return $verificationDigit; } function generateCuitCuil($typeCode, $dni = null) { // Kelvolliset tyyppikoodit $validTypeCodes = [20, 23, 24, 27, 30, 33, 34]; if (!in_array($typeCode, $validTypeCodes)) { throw new Exception("Virheellinen tyyppikoodi. Täytyy olla jokin seuraavista: " . implode(', ', $validTypeCodes)); } // Generoi satunnainen DNI, jos ei ole annettu if ($dni === null) { $dni = rand(10000000, 99999999); } // Laske tarkistenumero $verificationDigit = calculateVerificationDigit($typeCode, $dni); // Muotoile CUIT/CUIL return sprintf("%d-%08d-%d", $typeCode, $dni, $verificationDigit); } function validateCuitCuil($cuitCuil) { // Poista väliviivat, jos niitä on $cuitCuilClean = str_replace('-', '', $cuitCuil); // Tarkista perusmuoto if (!preg_match('/^\d{11}$/', $cuitCuilClean)) { return ['isValid' => false, 'errorMessage' => 'Virheellinen muoto']; } // Pura osat $typeCode = (int)substr($cuitCuilClean, 0, 2); $dni = (int)substr($cuitCuilClean, 2, 8); $verificationDigit = (int)substr($cuitCuilClean, 10, 1); ## Usein Kysytyt Kysymykset ### Mikä on ero CUIT:in ja CUIL:in välillä? Tässä käytännöllinen ero: **CUIT** (Clave Única de Identificación Tributaria) tunnistaa veronmaksajat – sekä yksityishenkilöt että yritykset, jotka jättävät veronsa AFIP:ille. **CUIL** (Clave Única de Identificación Laboral) tunnistaa työntekijät sosiaaliturvan järjestelmässä työllistymis- ja eläketarkoituksia varten. Käytännössä monilla henkilöillä on sekä CUIL (ensimmäisestä työstään) ja he saattavat myöhemmin saada CUIT:in (jos heistä tulee itsenäisiä ammatinharjoittajia tai he perustavat yrityksen). Numerot käyttävät identtistä muotoilua ja laskentasääntöjä, joten validoinnin kannalta niitä käsitellään samalla tavalla. Ero on merkityksellinen hallinnollisissa tarkoituksissa: palkanlaskentajärjestelmät tyypillisesti käyttävät CUIL:ia, kun taas laskutus- ja verojärjestelmät käyttävät CUIT:ia. ### Mitä tyyppikoodeja käytetään henkilöille ja mitä yrityksille? Henkilöille: - 20, 23, 24: Miespuoliset henkilöt (CUIL) - 27: Naispuoliset henkilöt (CUIL) Yrityksille ja organisaatioille: - 30: Yhtiöt (CUIT) - 33: Kansalaisjärjestöt (CUIT) - 34: Säätiöt (CUIT) ### Miten tarkistusnumero lasketaan? Algoritmi käyttää painotettua kertolaskua: ota ensimmäiset 10 numeroa, kerro painoarvoilla **5, 4, 3, 2, 7, 6, 5, 4, 3, 2**, summaa tulot, sitten laske 11 miinus (summa modulo 11). Kaksi erikoistapausta hämmentää ihmisiä: kun laskenta tuottaa 11, käytä 0:aa tarkistusnumerona; kun se tuottaa 10, käytä 9:ää. Nämä erikoistapaukset ovat olemassa, koska tarkistusnumeron täytyy olla yksi numero (0-9). Tämä on modulo-11 tarkistusnumerolaskenta, samankaltainen kuin ISBN-10-koodeissa ja muissa tunnistusjärjestelmissä maailmanlaajuisesti. ### Voinko käyttää tätä työkalua virallisten CUIT/CUIL-numeroiden luomiseen? Ei – tämä työkalu luo matemaattisesti kelvollisia testitietoja, mutta numerot eivät ole virallisesti rekisteröityjä AFIP:issa. Ajattele sitä kuin luottokorttinumeron generointia Luhn-algoritmilla: se läpäisee muotovalidoinnin, mutta se ei ole yhteydessä oikeaan tiliin. Viralliseen CUIT/CUIL-rekisteröintiin henkilöiden täytyy vierailla AFIP:issa DNI:nsä kanssa, kun taas yritysten täytyy suorittaa yritysrekisteröintimenettelyt. Työkalu on tarkoitettu yksinomaan kehitykseen, testaukseen ja koulutuskäyttöön, jossa tarvitaan valideja näyttäviä tietoja, jotka eivät ole ristiriidassa todellisten tunnistenumeroiden kanssa. (Käännös jatkuu samalla tavalla koko dokumentille) ## Lähteet 1. AFIP (Administración Federal de Ingresos Públicos). "CUIT/CUIL/CDI." Virallinen verkkosivusto. [https://www.afip.gob.ar/](https://www.afip.gob.ar/) 2. Työ-, työllisyys- ja sosiaaliturvaministeriö. "CUIL - Clave Única de Identificación Laboral." [https://www.argentina.gob.ar/trabajo](https://www.argentina.gob.ar/trabajo) 3. ANSES (Administración Nacional de la Seguridad Social). "Hanki oma CUIL." [https://www.anses.gob.ar/](https://www.anses.gob.ar/) 4. Argentiinan tasavallan virallinen lehti. "AFIP:n yleinen päätös 2854/2010: Menettely. Verotunniste (C.U.I.T.)." 5. Argentiinan tasavallan verolainsäädäntö. "Verovelvollisten tunnistaminen ja rekisteröinti." --- Olipa kyseessä laskutusjärjestelmän rakentaminen, työntekijöiden perehdytysprosessien testaaminen tai validointialgoritmien oppiminen, tämä työkalu tarjoaa tarvitsemasi CUIT/CUIL-generoinnin ja -validoinnin. Luo testidataa, joka läpäisee algoritmisen validoinnin, varmista numerot ennen tietokantaan vientiä tai tutustu tarkistusnumerolaskentaalgoritmin toimintaan käytännössä.