Guo Qiang

身份证号校验码的验证

发布日期 2020-11-07 18:36:35已读 192 次CODE
image

身份证号码18位数字,按从左到右数1-6位表示出生地编码,7-10位出生年份,11、12位出生月份,13、14位出生日期,15、16位出生顺序编号,17位性别标号,18位效验码。此算法只实现对第18位校验码的验证。


/*
设计函数检查身份证号校验码的正确性,该函数的原型和输入/出分别为:
int id_verifer(char id[]);
输入:表示身份证号的字符串;
输出:1--正确,0--错误

注:
18位身份证号码中的最后一位是校验码,它根据前面17位数字自动生成,校验码计算过程为:先求17位数的加权和S,然后求S对11的模,根据求模结果得到对应的校验码,主要公式及数据如下:

(1)十七位数字本体码加权求和公式
S = Sum(Ai * Wi),  i = 0, ... , 16,先对前17位数字的权求和
其中,Ai:表示第i位置上的身份证号码数字值,Wi:表示第i位置上的加权因子:
Wi:  7  9  10  5  8  4  2  1  6  3  7  9  10  5  8  4  2

(2)计算模
Y = mod (S, 11)

(3)通过模得到对应的校验码
Y:  0  1  2  3  4  5  6  7  8  9  10
校验码:   1   0   X   9   8   7   6   5   4   3   2
*/

#include <stdio.h>
#include <string.h>

int id_verifer(char id[])
{
	int w[17] = {7, 9 ,10 ,5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
	char check[17] = {'1','0','X','9','8','7','6','5','4','3','2'};

	int sum = 0;
	for (int i = 0; i < 17; i++)
		sum += (id[i] - '0') * w[i];

	int y = sum % 11;

	return (check[y] == id[17]);
}

int main()
{
	char id[19];

	printf("ID:");
	scanf("%s",id);

	if (id_verifer(id) == 1)
		printf("OK\n");
	else
		printf("ERROR\n");

	return 0;
}


Copyright © 2019~2021 Guo Qiang