身份证号码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;
}