首页 新闻动态 知识

统一社会信用代码校验码算法

发布时间:2025-04-18 16:48 点击:85

为了验证统一社会信用代码的最后一位校验码是否正确,我们可以按照以下步骤实现一个Python函数:

方法思路

  1. 字符集验证:统一社会信用代码由18位字符组成,包括数字0-9和大写字母(排除I、O、Z、S、V)。

  2. 字符到数值的映射:将前17位字符转换为对应的数值,其中数字直接转换,字母按特定规则转换。

  3. 权重计算:每个位置的权重为3的幂次模31的结果。

  4. 加权求和:计算前17位数值与对应权重的乘积之和。

  5. 校验码计算:根据加权和模31的结果确定校验码数值,再转换为对应字符。

解决代码

def checkCreditno(code):
    # 统一社会信用代码的字符到数值的映射
    char_map = {
        '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,
        'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15, 'G': 16, 'H': 17,
        'J': 18, 'K': 19, 'L': 20, 'M': 21, 'N': 22, 'P': 23, 'Q': 24, 'R': 25,
        'T': 26, 'U': 27, 'W': 28, 'X': 29, 'Y': 30
    }
    
    # 校验码数值到字符的映射
    value_map = {v: k for k, v in char_map.items() if k.isalpha() or k in '0123456789'}
    
    # 检查长度是否为18位
    if len(code) != 18:
        return False
    
    main_part = code[:17]
    check_char = code[17]
    
    # 检查前17位是否有效
    for c in main_part:
        if c not in char_map:
            return False
    
    # 检查校验位字符是否有效
    if check_char not in char_map:
        return False
    
    # 转换为数值列表
    nums = [char_map[c] for c in main_part]
    
    # 计算权重:3^i mod 31,i从0到16
    weights = [pow(3, i, 31) for i in range(17)]
    
    # 计算加权和
    total = sum(num * weight for num, weight in zip(nums, weights))
    
    # 计算校验码数值
    check_value = (31 - (total % 31)) % 31
    
    # 确定正确的校验字符
    if check_value < 10:
        expected_char = str(check_value)
    else:
        expected_char = value_map.get(check_value, None)
        if expected_char is None:
            return False  # 这种情况理论上不会发生
    
    # 比较校验字符
    return expected_char == check_char
check_result = checkCreditno('91110000802100433B')
print(check_result)


代码解释

  1. 字符映射:char_map定义了有效字符及其对应的数值,排除了一些易混淆的字母。

  2. 长度和字符检查:确保输入为18位,且所有字符有效。

  3. 数值转换:将前17位字符转换为对应的数值。

  4. 权重计算:使用3的幂次模31生成权重数组。

  5. 加权和与校验码计算:计算加权和后确定校验码数值,并转换为对应的校验字符。

  6. 结果验证:比较计算得到的校验字符与输入的最后一位是否一致,返回验证结果。

该方法严格遵循国家标准GB 32100-2015,确保校验过程准确可靠。