阿根廷CUIT/CUIL生成器和验证工具
生成有效的阿根廷CUIT/CUIL号码用于测试或验证现有号码。为处理阿根廷税务和劳动识别号码的开发人员提供的简单工具。
CUIT/CUIL 生成器
输入一个 8 位的 DNI 号码或使用随机生成器
生成的 CUIT/CUIL
文档
阿根廷 CUIT/CUIL 生成器和验证器
介绍
阿根廷的 CUIT(Clave Única de Identificación Tributaria)和 CUIL(Clave Única de Identificación Laboral)是用于阿根廷的唯一识别号码,分别用于税务和就业目的。这些 11 位数字代码对于个人和企业在阿根廷经济体系中合法运作至关重要。我们的 CUIT/CUIL 生成器和验证器工具提供了一种简单、高效的方法来生成有效的 CUIT/CUIL 号码以供测试,并验证现有号码以确保其符合官方格式和验证算法。
无论您是开发人员正在测试处理阿根廷税号的应用程序,还是 QA 专员验证系统功能,或只是想了解这些识别号码的工作原理,此工具都提供了一种简单的解决方案,而没有不必要的复杂性。该工具具有两个主要功能:一个生成器,可以随机生成有效的 CUIT/CUIL 号码或基于特定参数生成,另一个验证器可以验证给定的 CUIT/CUIL 号码是否遵循正确的格式和计算规则。
CUIT/CUIL 结构和计算
理解格式
有效的 CUIT/CUIL 号码由 11 位数字组成,通常以格式 XX-XXXXXXXX-X 显示:
-
类型代码(前 2 位数字):表示实体类型
- 20、23、24:男性个人(CUIL)
- 27:女性个人(CUIL)
- 30、33、34:公司和组织(CUIT)
-
DNI 号码(中间 8 位数字):对于个人,这是他们的国家身份证明文件号码(DNI),如果需要,前面用零填充以达到 8 位。对于公司,这是一个唯一的分配号码。
-
验证数字(最后一位数字):使用特定算法计算的校验位,用于验证整个号码。
验证数字计算
验证数字的计算方法如下:
- 取 CUIT/CUIL 的前 10 位数字(类型代码 + DNI)
- 将每位数字乘以以下权重序列中的相应权重:5、4、3、2、7、6、5、4、3、2
- 将所有结果相加
- 计算 11 减去总和除以 11 的余数
- 如果结果为 11,则验证数字为 0
- 如果结果为 10,则验证数字为 9
- 否则,结果即为验证数字
在数学上,这可以表示为:
其中:
- 是验证数字
- 是前 10 位数字中的第 位
- 是权重序列中的相应权重 [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
- 特殊情况:如果 则 ,如果 则
分步指南
使用生成器
-
选择工具界面顶部的“生成器”选项卡。
-
从下拉菜单中选择类型代码:
- 20:男性(CUIL)
- 23:企业(CUIT)
- 24:临时企业(CUIT)
- 27:女性(CUIL)
- 30:公司(CUIT)
- 33:民事协会(CUIT)
- 34:基金会(CUIT)
-
输入 DNI 号码(可选):
- 在提供的字段中输入 8 位 DNI 号码
- 如果留空,工具将使用随机生成的 DNI
- 如果您输入的位数少于 8 位,系统将用前导零填充
-
生成随机 DNI(可选):
- 点击“随机”按钮生成一个随机的 8 位 DNI 号码
-
查看生成的 CUIT/CUIL:
- 工具会根据您的输入自动显示有效的 CUIT/CUIL
- 格式将为 XX-XXXXXXXX-X,带有正确的验证数字
-
复制结果:
- 点击复制图标将生成的 CUIT/CUIL 复制到剪贴板
- 成功复制后会出现确认消息
使用验证器
-
选择工具界面顶部的“验证器”选项卡。
-
输入要验证的 CUIT/CUIL:
- 以格式 XX-XXXXXXXX-X 输入 CUIT/CUIL
- 工具会在您输入时自动用连字符格式化您的输入
- 您也可以输入没有连字符的号码(XXXXXXXXXXX)
-
点击“验证”按钮:
- 工具将检查格式、类型代码和验证数字
-
查看验证结果:
- 对于有效的 CUIT/CUIL 号码,将显示绿色成功消息
- 对于无效的号码,将显示红色错误消息,解释问题:
- 格式无效(必须为 XX-XXXXXXXX-X)
- 类型代码无效(必须为:20、23、24、27、30、33、34 之一)
- 验证数字无效
-
附加信息:
- 对于有效的号码,工具显示组件的详细信息:
- 类型代码及其含义
- DNI 号码
- 验证数字
- 对于有效的号码,工具显示组件的详细信息:
用例
开发和测试
-
软件开发:生成有效的 CUIT/CUIL 号码以测试处理阿根廷税务识别的应用程序,例如:
- 电子商务平台
- 会计软件
- 人力资源管理系统
- 政府服务门户
- 银行业务应用程序
-
数据库填充:为存储阿根廷用户信息的系统创建真实的测试数据,确保数据库约束和验证规则正常工作。
-
表单验证测试:测试收集 CUIT/CUIL 信息的网页表单的输入验证,验证无效条目是否出现适当的错误消息。
-
API 测试:生成有效的有效负载以供需要 CUIT/CUIL 号码的 API 端点,确保您的集成测试使用有效数据。
-
QA 自动化:将 CUIT/CUIL 生成纳入自动化测试脚本中,以创建动态测试用例,而不是使用静态测试数据。
教育目的
-
学习验证算法:通过观察 CUIT/CUIL 验证过程,了解校验位算法在实践中的工作原理。
-
教授数据验证:在教授新开发人员表单验证技术时,作为教育示例使用。
-
了解阿根廷商业要求:了解阿根廷用于国际商业发展的识别系统。
替代方案
虽然我们的工具提供了一种简单的方法来生成和验证 CUIT/CUIL 号码,但您可能考虑其他方法:
-
官方政府验证:对于生产环境,始终应根据官方 AFIP(Administración Federal de Ingresos Públicos)数据库验证 CUIT/CUIL 号码。
-
库和包:几种编程语言有专门用于阿根廷税号验证的库:
- JavaScript:
validar-cuit
npm 包 - PHP:
afip-php
库 - Python:
py-cuit
包
- JavaScript:
-
手动计算:出于教育目的,您可以使用前面描述的算法手动计算验证数字。
-
综合商业验证服务:对于企业应用程序,考虑使用综合验证服务,不仅检查格式,还验证与 CUIT/CUIL 相关的实体的存在性和状态。
CUIT/CUIL 系统的历史
阿根廷的 CUIT/CUIL 识别系统自创立以来经历了显著的发展:
起源和实施
CUIT(Clave Única de Identificación Tributaria)首次在 1970 年代引入阿根廷,作为现代化税收征收系统的努力的一部分。阿根廷联邦公共收入管理局(AFIP)实施了这一唯一标识符,以更有效地跟踪纳税人并减少逃税。
随后引入了 CUIL(Clave Única de Identificación Laboral),专门用于识别社会保障系统中的工人,创建了税务识别与劳动识别之间的区别,同时保持一致的格式。
发展和数字化
在 1990 年代,随着阿根廷经历重大经济改革,CUIT/CUIL 系统变得越来越重要,以跟踪经济活动。该系统进一步数字化,并实施了在线验证系统。
2000 年代初,CUIT/CUIL 系统与各种数字政府服务集成,使其成为阿根廷电子政府倡议的一个重要组成部分。这一时期还标准化了今天仍在使用的验证算法和格式。
最近的发展
近年来,AFIP 增强了 CUIT/CUIL 号码的安全性和验证过程,实施了更复杂的验证系统,并将其与其他政府数据库集成。该系统现在在阿根廷打击逃税和正规化经济的努力中发挥着关键作用。
如今,CUIT/CUIL 不仅用于税务和就业目的,还用于包括银行、财产交易、公用事业服务和在线购买在内的广泛活动,使其成为在阿根廷运营的个人和企业的必要标识符。
代码示例
Python
1def calculate_verification_digit(type_code, dni):
2 # 转换为字符串并确保 DNI 为 8 位,前面用零填充
3 type_code_str = str(type_code)
4 dni_str = str(dni).zfill(8)
5
6 # 组合类型代码和 DNI
7 digits = type_code_str + dni_str
8
9 # 每个位置的权重
10 weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
11
12 # 计算乘积之和
13 sum_products = sum(int(digits[i]) * weights[i] for i in range(10))
14
15 # 计算验证数字
16 verification_digit = 11 - (sum_products % 11)
17
18 # 特殊情况
19 if verification_digit == 11:
20 verification_digit = 0
21 elif verification_digit == 10:
22 verification_digit = 9
23
24 return verification_digit
25
26def generate_cuit_cuil(type_code, dni=None):
27 import random
28
29 # 有效的类型代码
30 valid_type_codes = [20, 23, 24, 27, 30, 33, 34]
31
32 if type_code not in valid_type_codes:
33 raise ValueError(f"无效的类型代码。必须是:{valid_type_codes}")
34
35 # 如果未提供,则生成随机 DNI
36 if dni is None:
37 dni = random.randint(10000000, 99999999)
38
39 # 计算验证数字
40 verification_digit = calculate_verification_digit(type_code, dni)
41
42 # 格式化 CUIT/CUIL
43 return f"{type_code}-{str(dni).zfill(8)}-{verification_digit}"
44
45def validate_cuit_cuil(cuit_cuil):
46 # 如果存在,去掉连字符
47 cuit_cuil_clean = cuit_cuil.replace("-", "")
48
49 # 检查基本格式
50 if not cuit_cuil_clean.isdigit() or len(cuit_cuil_clean) != 11:
51 return False, "格式无效"
52
53 # 提取部分
54 type_code = int(cuit_cuil_clean[0:2])
55 dni = int(cuit_cuil_clean[2:10])
56 verification_digit = int(cuit_cuil_clean[10])
57
58 # 验证类型代码
59 valid_type_codes = [20, 23, 24, 27, 30, 33, 34]
60 if type_code not in valid_type_codes:
61 return False, "类型代码无效"
62
63 # 计算并比较验证数字
64 calculated_digit = calculate_verification_digit(type_code, dni)
65 if calculated_digit != verification_digit:
66 return False, "验证数字无效"
67
68 return True, "有效的 CUIT/CUIL"
69
70# 示例用法
71print(generate_cuit_cuil(20, 12345678)) # 为特定 DNI 生成
72print(generate_cuit_cuil(27)) # 使用随机 DNI 生成
73print(validate_cuit_cuil("20-12345678-9")) # 验证 CUIT/CUIL
74
JavaScript
1function calculateVerificationDigit(typeCode, dni) {
2 // 转换为字符串并确保 DNI 为 8 位,前面用零填充
3 const typeCodeStr = typeCode.toString();
4 const dniStr = dni.toString().padStart(8, '0');
5
6 // 组合类型代码和 DNI
7 const digits = typeCodeStr + dniStr;
8
9 // 每个位置的权重
10 const weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
11
12 // 计算乘积之和
13 let sumProducts = 0;
14 for (let i = 0; i < 10; i++) {
15 sumProducts += parseInt(digits[i]) * weights[i];
16 }
17
18 // 计算验证数字
19 let verificationDigit = 11 - (sumProducts % 11);
20
21 // 特殊情况
22 if (verificationDigit === 11) {
23 verificationDigit = 0;
24 } else if (verificationDigit === 10) {
25 verificationDigit = 9;
26 }
27
28 return verificationDigit;
29}
30
31function generateCuitCuil(typeCode, dni) {
32 // 有效的类型代码
33 const validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
34
35 if (!validTypeCodes.includes(typeCode)) {
36 throw new Error(`无效的类型代码。必须是:${validTypeCodes.join(', ')}`);
37 }
38
39 // 如果未提供,则生成随机 DNI
40 if (dni === undefined) {
41 dni = Math.floor(Math.random() * 90000000) + 10000000;
42 }
43
44 // 计算验证数字
45 const verificationDigit = calculateVerificationDigit(typeCode, dni);
46
47 // 格式化 CUIT/CUIL
48 return `${typeCode}-${dni.toString().padStart(8, '0')}-${verificationDigit}`;
49}
50
51function validateCuitCuil(cuitCuil) {
52 // 如果存在,去掉连字符
53 const cuitCuilClean = cuitCuil.replace(/-/g, '');
54
55 // 检查基本格式
56 if (!/^\d{11}$/.test(cuitCuilClean)) {
57 return { isValid: false, errorMessage: '格式无效' };
58 }
59
60 // 提取部分
61 const typeCode = parseInt(cuitCuilClean.substring(0, 2));
62 const dni = parseInt(cuitCuilClean.substring(2, 10));
63 const verificationDigit = parseInt(cuitCuilClean.substring(10, 11));
64
65 // 验证类型代码
66 const validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
67 if (!validTypeCodes.includes(typeCode)) {
68 return { isValid: false, errorMessage: '类型代码无效' };
69 }
70
71 // 计算并比较验证数字
72 const calculatedDigit = calculateVerificationDigit(typeCode, dni);
73 if (calculatedDigit !== verificationDigit) {
74 return { isValid: false, errorMessage: '验证数字无效' };
75 }
76
77 return { isValid: true };
78}
79
80// 示例用法
81console.log(generateCuitCuil(20, 12345678)); // 为特定 DNI 生成
82console.log(generateCuitCuil(27)); // 使用随机 DNI 生成
83console.log(validateCuitCuil("20-12345678-9")); // 验证 CUIT/CUIL
84
Java
1import java.util.Arrays;
2import java.util.List;
3import java.util.Random;
4
5public class CuitCuilUtils {
6 private static final List<Integer> VALID_TYPE_CODES = Arrays.asList(20, 23, 24, 27, 30, 33, 34);
7 private static final int[] WEIGHTS = {5, 4, 3, 2, 7, 6, 5, 4, 3, 2};
8
9 public static int calculateVerificationDigit(int typeCode, int dni) {
10 // 转换为字符串并确保 DNI 为 8 位,前面用零填充
11 String typeCodeStr = String.valueOf(typeCode);
12 String dniStr = String.format("%08d", dni);
13
14 // 组合类型代码和 DNI
15 String digits = typeCodeStr + dniStr;
16
17 // 计算乘积之和
18 int sumProducts = 0;
19 for (int i = 0; i < 10; i++) {
20 sumProducts += Character.getNumericValue(digits.charAt(i)) * WEIGHTS[i];
21 }
22
23 // 计算验证数字
24 int verificationDigit = 11 - (sumProducts % 11);
25
26 // 特殊情况
27 if (verificationDigit == 11) {
28 verificationDigit = 0;
29 } else if (verificationDigit == 10) {
30 verificationDigit = 9;
31 }
32
33 return verificationDigit;
34 }
35
36 public static String generateCuitCuil(int typeCode, Integer dni) {
37 if (!VALID_TYPE_CODES.contains(typeCode)) {
38 throw new IllegalArgumentException("无效的类型代码。必须是: " + VALID_TYPE_CODES);
39 }
40
41 // 如果未提供,则生成随机 DNI
42 if (dni == null) {
43 Random random = new Random();
44 dni = 10000000 + random.nextInt(90000000);
45 }
46
47 // 计算验证数字
48 int verificationDigit = calculateVerificationDigit(typeCode, dni);
49
50 // 格式化 CUIT/CUIL
51 return String.format("%d-%08d-%d", typeCode, dni, verificationDigit);
52 }
53
54 public static ValidationResult validateCuitCuil(String cuitCuil) {
55 // 如果存在,去掉连字符
56 String cuitCuilClean = cuitCuil.replace("-", "");
57
58 // 检查基本格式
59 if (!cuitCuilClean.matches("\\d{11}")) {
60 return new ValidationResult(false, "格式无效");
61 }
62
63 // 提取部分
64 int typeCode = Integer.parseInt(cuitCuilClean.substring(0, 2));
65 int dni = Integer.parseInt(cuitCuilClean.substring(2, 10));
66 int verificationDigit = Integer.parseInt(cuitCuilClean.substring(10, 11));
67
68 // 验证类型代码
69 if (!VALID_TYPE_CODES.contains(typeCode)) {
70 return new ValidationResult(false, "类型代码无效");
71 }
72
73 // 计算并比较验证数字
74 int calculatedDigit = calculateVerificationDigit(typeCode, dni);
75 if (calculatedDigit != verificationDigit) {
76 return new ValidationResult(false, "验证数字无效");
77 }
78
79 return new ValidationResult(true, null);
80 }
81
82 public static class ValidationResult {
83 private final boolean isValid;
84 private final String errorMessage;
85
86 public ValidationResult(boolean isValid, String errorMessage) {
87 this.isValid = isValid;
88 this.errorMessage = errorMessage;
89 }
90
91 public boolean isValid() {
92 return isValid;
93 }
94
95 public String getErrorMessage() {
96 return errorMessage;
97 }
98 }
99
100 public static void main(String[] args) {
101 // 示例用法
102 System.out.println(generateCuitCuil(20, 12345678)); // 为特定 DNI 生成
103 System.out.println(generateCuitCuil(27, null)); // 使用随机 DNI 生成
104 System.out.println(validateCuitCuil("20-12345678-9").isValid()); // 验证 CUIT/CUIL
105 }
106}
107
PHP
1<?php
2
3function calculateVerificationDigit($typeCode, $dni) {
4 // 转换为字符串并确保 DNI 为 8 位,前面用零填充
5 $typeCodeStr = (string)$typeCode;
6 $dniStr = str_pad((string)$dni, 8, '0', STR_PAD_LEFT);
7
8 // 组合类型代码和 DNI
9 $digits = $typeCodeStr . $dniStr;
10
11 // 每个位置的权重
12 $weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
13
14 // 计算乘积之和
15 $sumProducts = 0;
16 for ($i = 0; $i < 10; $i++) {
17 $sumProducts += (int)$digits[$i] * $weights[$i];
18 }
19
20 // 计算验证数字
21 $verificationDigit = 11 - ($sumProducts % 11);
22
23 // 特殊情况
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 // 有效的类型代码
35 $validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
36
37 if (!in_array($typeCode, $validTypeCodes)) {
38 throw new Exception("无效的类型代码。必须是: " . implode(', ', $validTypeCodes));
39 }
40
41 // 如果未提供,则生成随机 DNI
42 if ($dni === null) {
43 $dni = rand(10000000, 99999999);
44 }
45
46 // 计算验证数字
47 $verificationDigit = calculateVerificationDigit($typeCode, $dni);
48
49 // 格式化 CUIT/CUIL
50 return sprintf("%d-%08d-%d", $typeCode, $dni, $verificationDigit);
51}
52
53function validateCuitCuil($cuitCuil) {
54 // 如果存在,去掉连字符
55 $cuitCuilClean = str_replace('-', '', $cuitCuil);
56
57 // 检查基本格式
58 if (!preg_match('/^\d{11}$/', $cuitCuilClean)) {
59 return ['isValid' => false, 'errorMessage' => '格式无效'];
60 }
61
62 // 提取部分
63 $typeCode = (int)substr($cuitCuilClean, 0, 2);
64 $dni = (int)substr($cuitCuilClean, 2, 8);
65 $verificationDigit = (int)substr($cuitCuilClean, 10, 1);
66
67 // 验证类型代码
68 $validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
69 if (!in_array($typeCode, $validTypeCodes)) {
70 return ['isValid' => false, 'errorMessage' => '类型代码无效'];
71 }
72
73 // 计算并比较验证数字
74 $calculatedDigit = calculateVerificationDigit($typeCode, $dni);
75 if ($calculatedDigit !== $verificationDigit) {
76 return ['isValid' => false, 'errorMessage' => '验证数字无效'];
77 }
78
79 return ['isValid' => true];
80}
81
82// 示例用法
83echo generateCuitCuil(20, 12345678) . "\n"; // 为特定 DNI 生成
84echo generateCuitCuil(27) . "\n"; // 使用随机 DNI 生成
85var_dump(validateCuitCuil("20-12345678-9")); // 验证 CUIT/CUIL
86?>
87
常见问题解答
CUIT 和 CUIL 之间有什么区别?
CUIT(Clave Única de Identificación Tributaria)用于税务识别,分配给需要在阿根廷缴税的个人和法人。CUIL(Clave Única de Identificación Laboral)专门用于工人,用于劳动和社会保障目的。虽然它们共享相同的格式和计算算法,但服务于不同的行政目的。
哪些类型代码用于个人,哪些用于公司?
对于个人:
- 20、23、24:男性个人(CUIL)
- 27:女性个人(CUIL)
对于公司和组织:
- 30:公司(CUIT)
- 33:民事协会(CUIT)
- 34:基金会(CUIT)
验证数字是如何计算的?
验证数字是使用加权和算法计算的。前 10 位数字中的每一位乘以相应的权重(5、4、3、2、7、6、5、4、3、2),结果相加。验证数字为 11 减去该总和除以 11 的余数。特殊情况:如果结果为 11,则验证数字为 0;如果结果为 10,则验证数字为 9。
我可以使用此工具生成真实的官方 CUIT/CUIL 号码吗?
不可以,此工具仅用于测试和教育目的。生成的号码根据 CUIT/CUIL 算法在数学上是有效的,但未在阿根廷税务机关(AFIP)正式注册。要正式注册 CUIT/CUIL,个人和公司必须遵循通过 AFIP 的适当法律程序。
为什么我的 CUIT/CUIL 验证失败,即使格式看起来正确?
验证可能失败的原因有几个:
- 类型代码不是有效代码(20、23、24、27、30、33、34 之一)
- 验证数字与根据算法计算的值不匹配
- 格式不正确(应为 XX-XXXXXXXX-X)
- 输入中存在非数字字符(除了连字符)
CUIT/CUIL 号码中是否需要连字符?
虽然 CUIT/CUIL 号码通常以连字符(XX-XXXXXXXX-X)书写和显示,但连字符并不是计算目的的实际号码。我们的验证器接受两种格式(带或不带连字符),并会正确验证任一格式。
CUIT/CUIL 的 DNI 部分可以少于 8 位吗?
不可以,DNI 部分必须始终为 8 位。如果实际 DNI 少于 8 位,则必须用前导零填充以达到 8 位。例如,如果某人的 DNI 为 1234567,则在 CUIT/CUIL 中表示为 01234567。
我如何验证 CUIT/CUIL 是否在阿根廷正式注册?
要验证 CUIT/CUIL 是否正式注册并处于活动状态,您应使用官方 AFIP(Administración Federal de Ingresos Públicos)网站或服务。我们的工具仅验证号码的数学有效性,而不验证其官方注册状态。
我可以在商业应用中使用此工具吗?
是的,您可以将此工具中演示的算法和逻辑集成到您的商业应用中。CUIT/CUIL 验证算法是公共标准。然而,对于生产环境,我们建议实施适当的错误处理,并在必要时考虑针对官方来源的额外验证。
此工具是否存储任何生成或验证的 CUIT/CUIL 号码?
不,这个工具不存储任何输入或生成的信息。所有处理都是在您的浏览器中进行的,没有数据发送到或存储在我们的服务器上。这确保了您输入的任何信息的隐私和安全性。
参考文献
-
AFIP(Administración Federal de Ingresos Públicos)。“CUIT/CUIL/CDI。”官方网站。https://www.afip.gob.ar/
-
劳动、就业和社会保障部。“CUIL - Clave Única de Identificación Laboral。”https://www.argentina.gob.ar/trabajo
-
ANSES(国家社会保障管理局)。“获取我的 CUIL。”https://www.anses.gob.ar/
-
阿根廷共和国官方公报。“AFIP 第 2854/2010 号决议:程序。Clave Única de Identificación Tributaria (C.U.I.T.)。”
-
阿根廷共和国税法。“纳税人识别和注册。”
准备好生成或验证阿根廷 CUIT/CUIL 号码了吗?立即尝试我们的工具,简化您的测试过程!
反馈
点击反馈提示开始给这个工具反馈