身份证我们都人手一个,可是你知道身份证是怎么得来的吗?又怎么验证一个身份证号是不是真实的身份证呢?下面来看看吧。
我国国标〖GB 11643-1999〗中规定:
公民身份号码是18位特征组合码,由十七位数字本体码和一位数字校验码组成。
排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。地址码就是出身地址的一个编码,出生日期就是生日,顺序码应该是办身份证给你登记的一个序号,而数字校验码则是对前面17个数字校验得到的。校验码的计算过程如下:
其校验码(最后一位)计算方法和步骤为:
(1)十七位数字本体码加权求和公式
S = Sum(Ai * Wi), i = 0, ... , 16 ,
先对前17位数字的权求和,其中:
Ai:表示第i位置上的身份证号码数字值
Wi:表示第i位置上的加权因子,前17位加权因子从左到右分别为 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2。如下图所示
(2)计算模
Y = mod(S, 11),就是取模的意思,代码中就是 Y = S % 11
(3)通过模Y查下表得到对应的校验码
例如:某身份证前17位为11010519491231002
得到和为:167;则模为y=167%11=2
查(3)得校验码为X(大写),所以他的身份证号为:11010519491231002X
这个校验,你写的出来吗?其实不难哦。试试看吧。
下面我给出我的代码实现,仅供参考。
#include <stdio.h>
#include <stdlib.h>
const int Wi[] = { 7, 9 ,10, 5, 8 ,4, 2 ,1 ,6 ,3 ,7 ,9 ,10 ,5 ,8 ,4 ,2 };
const int Jym[] = {1,0, 10, 9, 8, 7, 6, 5, 4,3, 2};
int GetSum(const char * num)
{
// - 返回加权和
int iSum = 0;
int temp;
char ch;
for (int i = 0; i < 17; i++)
{
ch = num[i];
temp = atoi(&ch);
iSum += temp*Wi[i];
}
return iSum;
}
int GetJym(int num)
{
// - 获取校验码
return Jym[num];
}
int Jy(const char*sfz ,int jy)
{
// - 校验身份证号是否正确
int iLast = -1;
char ch = sfz[17];
if (sfz[17] == 'X')
iLast = 10;
else
iLast = atoi(&ch);
if (iLast == jy)
return 1;
else
return 0;
}
void main()
{
char sfz[19] = "";
scanf("%s", &sfz);
int iSun = GetSum(sfz);
int iMod = iSun % 11;
char iJym = GetJym(iMod);
int iRet = Jy(sfz, iJym);
printf("%d\n", iRet);
}
代码的逻辑就是上的描述,所以没什么好解释的。最好是自己动手写一遍再看哦。这个作为算法思维训练,解决实际问题的一个练习了。请一定要动手哦。后面将会拿更多的能够解决实际问题的算法来练习。提高大家的解决实际问题的能力。