原来的一代身份证号是15位的,现在用的二代身份证号是18位的,它们之间有一个转换规则。
一代:340524800101001
二代:34052419800101001X
可以看到它们之间的区别是二代在年份前多了19,最后面多了一位校验位
第十八位数字的计算方法为:
1.将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
2.将这17位数字和系数相乘的结果相加。
3.用加出来和除以11,看余数是多少?
4余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3 2。
5.通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最后一位号码就是2。
以下代码VC6编译测试通过:
#include<stdio.h> #include<string.h> void id_card_convert(char * id) { char tmp[20]; int i, j ,sum = 0; char verify[11] = {'1','0','X','9','8','7','6','5','4','3','2'};//校验位 int num[17] = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};//系数 //转换号码15位到18位 memset(tmp, 0x00, sizeof(tmp)); memcpy(tmp, id, 6);//复制前6位 memcpy(&tmp[6], "19", 2);//前6位后补19 memcpy(&tmp[8], id+6, 9);//复制后9位 for (i = 0; i < 17; i++)//现在tmp有17位算第18位校验位 { sum = sum + (tmp[i]-0x30)*num[i]; } j = sum % 11;//从verify数组中找到第j位就是校验值 tmp[17] = verify[j]; memcpy(id, tmp, 20); } void main() { char id_card[20]; memset(id_card, 0x00, sizeof(id_card)); memcpy(id_card, "340524800101001", 15); printf("原身份证号:%s\n", id_card); id_card_convert(id_card); printf("转换后:%s\n", id_card); //显示34052419800101001X是正确值 }
参考资料:
http://blog.csdn.net/ylqmf/article/details/4904483