🛠️

Whiz Tools

Build • Create • Innovate

Argentinian CUIT/CUIL Generator and Validator Tool

Generate valid Argentinian CUIT/CUIL numbers for testing or validate existing ones. Simple tool for developers working with Argentinian tax and labor identification numbers.

CUIT/CUIL Generator

Enter an 8-digit DNI number or use the random generator

Generated CUIT/CUIL

📚

Documentation

Argentinian CUIT/CUIL Generator and Validator

Introduction

The Argentinian CUIT (Clave Única de Identificación Tributaria) and CUIL (Clave Única de Identificación Laboral) are unique identification numbers used in Argentina for tax and employment purposes, respectively. These 11-digit codes are essential for individuals and businesses to operate legally within the Argentinian economic system. Our CUIT/CUIL Generator and Validator tool provides a simple, efficient way to generate valid CUIT/CUIL numbers for testing purposes and validate existing numbers to ensure they conform to the official format and verification algorithm.

Whether you're a developer testing applications that handle Argentinian tax IDs, a QA specialist verifying system functionality, or simply need to understand how these identification numbers work, this tool offers a straightforward solution without unnecessary complexities. The tool features two primary functions: a generator that creates valid CUIT/CUIL numbers randomly or based on specific parameters, and a validator that verifies whether a given CUIT/CUIL number follows the correct format and calculation rules.

CUIT/CUIL Structure and Calculation

Understanding the Format

A valid CUIT/CUIL number consists of 11 digits typically displayed in the format XX-XXXXXXXX-X:

  1. Type Code (first 2 digits): Indicates the entity type

    • 20, 23, 24: Male individuals (CUIL)
    • 27: Female individuals (CUIL)
    • 30, 33, 34: Companies and organizations (CUIT)
  2. DNI Number (middle 8 digits): For individuals, this is their national identity document number (DNI), padded with leading zeros if necessary to reach 8 digits. For companies, this is a unique assigned number.

  3. Verification Digit (last digit): A check digit calculated using a specific algorithm to validate the entire number.

Verification Digit Calculation

The verification digit is calculated using the following algorithm:

  1. Take the first 10 digits of the CUIT/CUIL (type code + DNI)
  2. Multiply each digit by a corresponding weight from this sequence: 5, 4, 3, 2, 7, 6, 5, 4, 3, 2
  3. Sum all the resulting products
  4. Calculate 11 minus the remainder of the sum divided by 11
  5. If the result is 11, the verification digit is 0
  6. If the result is 10, the verification digit is 9
  7. Otherwise, the result is the verification digit

Mathematically, this can be expressed as:

VD=11((i=110di×wi)mod11)VD = 11 - ((\sum_{i=1}^{10} d_i \times w_i) \bmod 11)

Where:

  • VDVD is the verification digit
  • did_i is the ii-th digit of the first 10 digits
  • wiw_i is the corresponding weight from the sequence [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
  • Special cases: if VD=11VD = 11 then VD=0VD = 0, if VD=10VD = 10 then VD=9VD = 9

Step-by-Step Guide

Using the Generator

  1. Select the "Generator" tab at the top of the tool interface.

  2. Choose a Type Code from the dropdown menu:

    • 20: Male (CUIL)
    • 23: Business (CUIT)
    • 24: Temporary Business (CUIT)
    • 27: Female (CUIL)
    • 30: Corporation (CUIT)
    • 33: Civil Association (CUIT)
    • 34: Foundation (CUIT)
  3. Enter a DNI Number (optional):

    • Input an 8-digit DNI number in the field provided
    • If left empty, the tool will use a randomly generated DNI
    • If you enter fewer than 8 digits, the system will pad with leading zeros
  4. Generate Random DNI (optional):

    • Click the "Random" button to generate a random 8-digit DNI number
  5. View the Generated CUIT/CUIL:

    • The tool automatically displays a valid CUIT/CUIL based on your inputs
    • The format will be XX-XXXXXXXX-X with the correct verification digit
  6. Copy the Result:

    • Click the copy icon to copy the generated CUIT/CUIL to your clipboard
    • A confirmation message will appear when copied successfully

Using the Validator

  1. Select the "Validator" tab at the top of the tool interface.

  2. Enter the CUIT/CUIL to Validate:

    • Input the CUIT/CUIL in the format XX-XXXXXXXX-X
    • The tool will automatically format your input with hyphens as you type
    • You can also enter the number without hyphens (XXXXXXXXXXX)
  3. Click the "Validate" Button:

    • The tool will check the format, type code, and verification digit
  4. View the Validation Result:

    • For valid CUIT/CUIL numbers, a green success message will appear
    • For invalid numbers, a red error message will explain the issue:
      • Invalid format (must be XX-XXXXXXXX-X)
      • Invalid type code (must be one of: 20, 23, 24, 27, 30, 33, 34)
      • Invalid verification digit
  5. Additional Information:

    • For valid numbers, the tool displays a breakdown of the components:
      • Type code and its meaning
      • DNI number
      • Verification digit

Use Cases

Development and Testing

  1. Software Development: Generate valid CUIT/CUIL numbers to test applications that handle Argentinian tax identification, such as:

    • E-commerce platforms
    • Accounting software
    • HR management systems
    • Government service portals
    • Banking applications
  2. Database Population: Create realistic test data for systems that store Argentinian user information, ensuring that database constraints and validation rules work correctly.

  3. Form Validation Testing: Test input validation for web forms that collect CUIT/CUIL information, verifying that proper error messages appear for invalid entries.

  4. API Testing: Generate valid payloads for API endpoints that require CUIT/CUIL numbers, ensuring that your integration tests use valid data.

  5. QA Automation: Incorporate CUIT/CUIL generation into automated test scripts to create dynamic test cases rather than using static test data.

Educational Purposes

  1. Learning Validation Algorithms: Understand how check digit algorithms work in practice by seeing the CUIT/CUIL verification process in action.

  2. Teaching Data Validation: Use as an educational example when teaching form validation techniques to new developers.

  3. Understanding Argentinian Business Requirements: Learn about the identification system used in Argentina for international business development.

Alternatives

While our tool provides a straightforward way to generate and validate CUIT/CUIL numbers, there are alternative approaches you might consider:

  1. Official Government Validation: For production environments, always validate CUIT/CUIL numbers against the official AFIP (Administración Federal de Ingresos Públicos) database when possible.

  2. Libraries and Packages: Several programming languages have libraries specifically designed for Argentinian tax ID validation:

    • JavaScript: validar-cuit npm package
    • PHP: afip-php library
    • Python: py-cuit package
  3. Manual Calculation: For educational purposes, you might calculate the verification digit manually using the algorithm described earlier.

  4. Comprehensive Business Validation Services: For enterprise applications, consider using comprehensive validation services that not only check the format but also verify the existence and status of the entity associated with the CUIT/CUIL.

History of the CUIT/CUIL System

The CUIT/CUIL identification system in Argentina has evolved significantly since its inception:

Origins and Implementation

The CUIT (Clave Única de Identificación Tributaria) was first introduced in Argentina in the 1970s as part of efforts to modernize the tax collection system. The Federal Administration of Public Revenue (AFIP) implemented this unique identifier to track taxpayers more efficiently and reduce tax evasion.

The CUIL (Clave Única de Identificación Laboral) was later introduced to specifically identify workers in the social security system, creating a distinction between tax identification and labor identification while maintaining a consistent format.

Evolution and Digitalization

In the 1990s, as Argentina underwent significant economic reforms, the CUIT/CUIL system became increasingly important for tracking economic activity. The system was further digitalized, and online verification systems were implemented.

The early 2000s saw the integration of the CUIT/CUIL system with various digital government services, making it an essential component of Argentina's e-government initiatives. This period also saw the standardization of the verification algorithm and format that remains in use today.

Recent Developments

In recent years, the AFIP has enhanced the security and verification processes for CUIT/CUIL numbers, implementing more sophisticated validation systems and integrating them with other government databases. The system now plays a crucial role in Argentina's efforts to combat tax evasion and formalize the economy.

Today, the CUIT/CUIL is used not only for tax and employment purposes but also for a wide range of activities including banking, property transactions, utility services, and online purchases, making it an essential identifier for both individuals and businesses operating in Argentina.

Code Examples

Python

1def calculate_verification_digit(type_code, dni):
2    # Convert to string and ensure DNI is 8 digits with leading zeros
3    type_code_str = str(type_code)
4    dni_str = str(dni).zfill(8)
5    
6    # Combine type code and DNI
7    digits = type_code_str + dni_str
8    
9    # Weights for each position
10    weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
11    
12    # Calculate sum of products
13    sum_products = sum(int(digits[i]) * weights[i] for i in range(10))
14    
15    # Calculate verification digit
16    verification_digit = 11 - (sum_products % 11)
17    
18    # Special cases
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    # Valid type codes
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"Invalid type code. Must be one of: {valid_type_codes}")
34    
35    # Generate random DNI if not provided
36    if dni is None:
37        dni = random.randint(10000000, 99999999)
38    
39    # Calculate verification digit
40    verification_digit = calculate_verification_digit(type_code, dni)
41    
42    # Format CUIT/CUIL
43    return f"{type_code}-{str(dni).zfill(8)}-{verification_digit}"
44
45def validate_cuit_cuil(cuit_cuil):
46    # Remove hyphens if present
47    cuit_cuil_clean = cuit_cuil.replace("-", "")
48    
49    # Check basic format
50    if not cuit_cuil_clean.isdigit() or len(cuit_cuil_clean) != 11:
51        return False, "Invalid format"
52    
53    # Extract parts
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    # Validate type code
59    valid_type_codes = [20, 23, 24, 27, 30, 33, 34]
60    if type_code not in valid_type_codes:
61        return False, "Invalid type code"
62    
63    # Calculate and compare verification digit
64    calculated_digit = calculate_verification_digit(type_code, dni)
65    if calculated_digit != verification_digit:
66        return False, "Invalid verification digit"
67    
68    return True, "Valid CUIT/CUIL"
69
70# Example usage
71print(generate_cuit_cuil(20, 12345678))  # Generate for specific DNI
72print(generate_cuit_cuil(27))  # Generate with random DNI
73print(validate_cuit_cuil("20-12345678-9"))  # Validate a CUIT/CUIL
74

JavaScript

1function calculateVerificationDigit(typeCode, dni) {
2  // Convert to string and ensure DNI is 8 digits with leading zeros
3  const typeCodeStr = typeCode.toString();
4  const dniStr = dni.toString().padStart(8, '0');
5  
6  // Combine type code and DNI
7  const digits = typeCodeStr + dniStr;
8  
9  // Weights for each position
10  const weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
11  
12  // Calculate sum of products
13  let sumProducts = 0;
14  for (let i = 0; i < 10; i++) {
15    sumProducts += parseInt(digits[i]) * weights[i];
16  }
17  
18  // Calculate verification digit
19  let verificationDigit = 11 - (sumProducts % 11);
20  
21  // Special cases
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  // Valid type codes
33  const validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
34  
35  if (!validTypeCodes.includes(typeCode)) {
36    throw new Error(`Invalid type code. Must be one of: ${validTypeCodes.join(', ')}`);
37  }
38  
39  // Generate random DNI if not provided
40  if (dni === undefined) {
41    dni = Math.floor(Math.random() * 90000000) + 10000000;
42  }
43  
44  // Calculate verification digit
45  const verificationDigit = calculateVerificationDigit(typeCode, dni);
46  
47  // Format CUIT/CUIL
48  return `${typeCode}-${dni.toString().padStart(8, '0')}-${verificationDigit}`;
49}
50
51function validateCuitCuil(cuitCuil) {
52  // Remove hyphens if present
53  const cuitCuilClean = cuitCuil.replace(/-/g, '');
54  
55  // Check basic format
56  if (!/^\d{11}$/.test(cuitCuilClean)) {
57    return { isValid: false, errorMessage: 'Invalid format' };
58  }
59  
60  // Extract parts
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  // Validate type code
66  const validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
67  if (!validTypeCodes.includes(typeCode)) {
68    return { isValid: false, errorMessage: 'Invalid type code' };
69  }
70  
71  // Calculate and compare verification digit
72  const calculatedDigit = calculateVerificationDigit(typeCode, dni);
73  if (calculatedDigit !== verificationDigit) {
74    return { isValid: false, errorMessage: 'Invalid verification digit' };
75  }
76  
77  return { isValid: true };
78}
79
80// Example usage
81console.log(generateCuitCuil(20, 12345678)); // Generate for specific DNI
82console.log(generateCuitCuil(27)); // Generate with random DNI
83console.log(validateCuitCuil("20-12345678-9")); // Validate a CUIT/CUIL
84

Java

1import java.util.Arrays;
2import java.util.List;
3import java.util.Random;
4
5public class CuitCuilUtils {
6    private static final List<Integer> VALID_TYPE_CODES = Arrays.asList(20, 23, 24, 27, 30, 33, 34);
7    private static final int[] WEIGHTS = {5, 4, 3, 2, 7, 6, 5, 4, 3, 2};
8    
9    public static int calculateVerificationDigit(int typeCode, int dni) {
10        // Convert to string and ensure DNI is 8 digits with leading zeros
11        String typeCodeStr = String.valueOf(typeCode);
12        String dniStr = String.format("%08d", dni);
13        
14        // Combine type code and DNI
15        String digits = typeCodeStr + dniStr;
16        
17        // Calculate sum of products
18        int sumProducts = 0;
19        for (int i = 0; i < 10; i++) {
20            sumProducts += Character.getNumericValue(digits.charAt(i)) * WEIGHTS[i];
21        }
22        
23        // Calculate verification digit
24        int verificationDigit = 11 - (sumProducts % 11);
25        
26        // Special cases
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("Invalid type code. Must be one of: " + VALID_TYPE_CODES);
39        }
40        
41        // Generate random DNI if not provided
42        if (dni == null) {
43            Random random = new Random();
44            dni = 10000000 + random.nextInt(90000000);
45        }
46        
47        // Calculate verification digit
48        int verificationDigit = calculateVerificationDigit(typeCode, dni);
49        
50        // Format CUIT/CUIL
51        return String.format("%d-%08d-%d", typeCode, dni, verificationDigit);
52    }
53    
54    public static ValidationResult validateCuitCuil(String cuitCuil) {
55        // Remove hyphens if present
56        String cuitCuilClean = cuitCuil.replace("-", "");
57        
58        // Check basic format
59        if (!cuitCuilClean.matches("\\d{11}")) {
60            return new ValidationResult(false, "Invalid format");
61        }
62        
63        // Extract parts
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        // Validate type code
69        if (!VALID_TYPE_CODES.contains(typeCode)) {
70            return new ValidationResult(false, "Invalid type code");
71        }
72        
73        // Calculate and compare verification digit
74        int calculatedDigit = calculateVerificationDigit(typeCode, dni);
75        if (calculatedDigit != verificationDigit) {
76            return new ValidationResult(false, "Invalid verification digit");
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        // Example usage
102        System.out.println(generateCuitCuil(20, 12345678)); // Generate for specific DNI
103        System.out.println(generateCuitCuil(27, null)); // Generate with random DNI
104        System.out.println(validateCuitCuil("20-12345678-9").isValid()); // Validate a CUIT/CUIL
105    }
106}
107

PHP

1<?php
2
3function calculateVerificationDigit($typeCode, $dni) {
4    // Convert to string and ensure DNI is 8 digits with leading zeros
5    $typeCodeStr = (string)$typeCode;
6    $dniStr = str_pad((string)$dni, 8, '0', STR_PAD_LEFT);
7    
8    // Combine type code and DNI
9    $digits = $typeCodeStr . $dniStr;
10    
11    // Weights for each position
12    $weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
13    
14    // Calculate sum of products
15    $sumProducts = 0;
16    for ($i = 0; $i < 10; $i++) {
17        $sumProducts += (int)$digits[$i] * $weights[$i];
18    }
19    
20    // Calculate verification digit
21    $verificationDigit = 11 - ($sumProducts % 11);
22    
23    // Special cases
24    if ($verificationDigit == 11) {
25        $verificationDigit = 0;
26    } else if ($verificationDigit == 10) {
27        $verificationDigit = 9;
28    }
29    
30    return $verificationDigit;
31}
32
33function generateCuitCuil($typeCode, $dni = null) {
34    // Valid type codes
35    $validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
36    
37    if (!in_array($typeCode, $validTypeCodes)) {
38        throw new Exception("Invalid type code. Must be one of: " . implode(', ', $validTypeCodes));
39    }
40    
41    // Generate random DNI if not provided
42    if ($dni === null) {
43        $dni = rand(10000000, 99999999);
44    }
45    
46    // Calculate verification digit
47    $verificationDigit = calculateVerificationDigit($typeCode, $dni);
48    
49    // Format CUIT/CUIL
50    return sprintf("%d-%08d-%d", $typeCode, $dni, $verificationDigit);
51}
52
53function validateCuitCuil($cuitCuil) {
54    // Remove hyphens if present
55    $cuitCuilClean = str_replace('-', '', $cuitCuil);
56    
57    // Check basic format
58    if (!preg_match('/^\d{11}$/', $cuitCuilClean)) {
59        return ['isValid' => false, 'errorMessage' => 'Invalid format'];
60    }
61    
62    // Extract parts
63    $typeCode = (int)substr($cuitCuilClean, 0, 2);
64    $dni = (int)substr($cuitCuilClean, 2, 8);
65    $verificationDigit = (int)substr($cuitCuilClean, 10, 1);
66    
67    // Validate type code
68    $validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
69    if (!in_array($typeCode, $validTypeCodes)) {
70        return ['isValid' => false, 'errorMessage' => 'Invalid type code'];
71    }
72    
73    // Calculate and compare verification digit
74    $calculatedDigit = calculateVerificationDigit($typeCode, $dni);
75    if ($calculatedDigit !== $verificationDigit) {
76        return ['isValid' => false, 'errorMessage' => 'Invalid verification digit'];
77    }
78    
79    return ['isValid' => true];
80}
81
82// Example usage
83echo generateCuitCuil(20, 12345678) . "\n"; // Generate for specific DNI
84echo generateCuitCuil(27) . "\n"; // Generate with random DNI
85var_dump(validateCuitCuil("20-12345678-9")); // Validate a CUIT/CUIL
86?>
87

Frequently Asked Questions

What is the difference between CUIT and CUIL?

CUIT (Clave Única de Identificación Tributaria) is used for tax identification purposes and is assigned to both individuals and legal entities that need to pay taxes in Argentina. CUIL (Clave Única de Identificación Laboral) is specifically for workers and is used for labor and social security purposes. While they share the same format and calculation algorithm, they serve different administrative purposes.

Which type codes are used for individuals and which for companies?

For individuals:

  • 20, 23, 24: Male individuals (CUIL)
  • 27: Female individuals (CUIL)

For companies and organizations:

  • 30: Corporations (CUIT)
  • 33: Civil Associations (CUIT)
  • 34: Foundations (CUIT)

How is the verification digit calculated?

The verification digit is calculated using a weighted sum algorithm. Each of the first 10 digits is multiplied by a corresponding weight (5, 4, 3, 2, 7, 6, 5, 4, 3, 2), and the results are summed. The verification digit is 11 minus the remainder when this sum is divided by 11. Special cases: if the result is 11, the verification digit is 0; if the result is 10, the verification digit is 9.

Can I use this tool to generate real, official CUIT/CUIL numbers?

No, this tool is designed for testing and educational purposes only. The numbers generated are mathematically valid according to the CUIT/CUIL algorithm but are not officially registered with the Argentinian tax authorities (AFIP). For official CUIT/CUIL registration, individuals and companies must follow the proper legal procedures through AFIP.

Why does my CUIT/CUIL validation fail even though the format looks correct?

Validation can fail for several reasons:

  1. The type code is not one of the valid codes (20, 23, 24, 27, 30, 33, 34)
  2. The verification digit does not match the calculated value based on the algorithm
  3. The format is incorrect (should be XX-XXXXXXXX-X)
  4. There are non-numeric characters in the input (apart from hyphens)

Are hyphens required in CUIT/CUIL numbers?

While CUIT/CUIL numbers are commonly written and displayed with hyphens (XX-XXXXXXXX-X), the hyphens are not part of the actual number for calculation purposes. Our validator accepts both formats (with or without hyphens) and will properly validate either format.

Can a CUIT/CUIL number have fewer than 8 digits in the DNI portion?

No, the DNI portion must always be exactly 8 digits. If the actual DNI has fewer digits, it must be padded with leading zeros to reach 8 digits. For example, if someone's DNI is 1234567, in the CUIT/CUIL it would be represented as 01234567.

How can I verify if a CUIT/CUIL is officially registered in Argentina?

To verify if a CUIT/CUIL is officially registered and active, you should use the official AFIP (Administración Federal de Ingresos Públicos) website or services. Our tool only verifies the mathematical validity of the number, not its official registration status.

Can I use this tool in my commercial application?

Yes, you can integrate the algorithm and logic demonstrated in this tool into your commercial applications. The CUIT/CUIL validation algorithm is a public standard. However, for production environments, we recommend implementing proper error handling and considering additional validation against official sources when necessary.

Does the tool store any of the generated or validated CUIT/CUIL numbers?

No, this tool does not store any of the information entered or generated. All processing is done client-side in your browser, and no data is sent to or stored on our servers. This ensures the privacy and security of any information you enter.

References

  1. AFIP (Administración Federal de Ingresos Públicos). "CUIT/CUIL/CDI." Official Website. https://www.afip.gob.ar/

  2. Ministerio de Trabajo, Empleo y Seguridad Social. "CUIL - Clave Única de Identificación Laboral." https://www.argentina.gob.ar/trabajo

  3. ANSES (Administración Nacional de la Seguridad Social). "Obtener mi CUIL." https://www.anses.gob.ar/

  4. Boletín Oficial de la República Argentina. "Resolución General AFIP 2854/2010: Procedimiento. Clave Única de Identificación Tributaria (C.U.I.T.)."

  5. Código Fiscal de la República Argentina. "Identificación y Registro de Contribuyentes."


Ready to generate or validate Argentinian CUIT/CUIL numbers? Try our tool now and simplify your testing process!