第二代身份证号码由18位数字组成,其各位数字的意义是:第一位表示地区:1华北地区,2东北地区,3华东地区,4中南地区,5西南地区,6西北地区,7台湾,8港澳。
第一二位合起来表示省或直辖市:11北京市,12天津市,13河北省,14山西省,15内蒙古。21辽宁省,22吉林省,23黑龙江省。31上海市,32江苏省,33浙江省,34安徽省,35福建省,36江西省,37山东省。41河南省,42湖北省,43湖南省,44广东省,45广西省,46海南省。50重庆市,51四川省,52贵州省,53云南省,54西藏。61陕西省,62甘肃省,63青海省,64宁夏省,65新疆。71台湾。81香港,82澳门。
第三四位表示市,以陕西省为例:01西安市,02铜川市,03宝鸡市,04咸阳市,05渭南市,06延安市,07汉中市,08榆林市,09安康市,10商洛市。
第五六位表示区县,以铜川市为例:02王益区,03印台区,04耀州区,21耀县,22宜君县。
第七至十四位表示出生年、月、日:其中年4位,月2位,日2位。
第十五至十七位表示初次办身份证时或初次登记户口时,在所辖派出所登记的顺序及性别,其中第十七位也就是倒数第二位为单数(奇数)时代表男,为双数(偶数)时代表女。
第十八位为校验码,其计算方法为:给身份证号码的第一至十七位数字分别乘以加权系数:7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,即第一位数字乘以7,第二位数字乘以9,第三位数字乘以10……第十六位数字乘以4,第十七位数字乘以2,把所得十七个乘积相加求出总和,再用总和除以11,所得余数只能有0,1,2,3,4,5,6,7,8,9,10共十一个,这些余数对应的校验码分别是:1 0 10 9 8 7 6 5 4 3 2 就是第十八位的校验码。但是,10是两位数,如果写成10身份证号码就变成19位啦,为了保证所有人的身份证号码都是十八位,所以对校验码是10的就用罗马数字中表示10的x代表10。
假如某人的身份证号码为:680213202104244136,可知其是西北某省人,2021年4月24日出生在所辖派出所报户口的第二个男孩,其校验码计算过程如下:6*7 8*9 0*10 2*5 1*8 3*4 2*2 0*1 2*6 1*3 0*7 4*9 2*10 4*5 4*8 1*4 3*2=281,用281除以11得到余数7,对应的校验码是6,在18位号码中只要有一位错误,校验码就对不上。
现把本人用C语言编写的计算身份证的校验码及检查身份证号码是否有错误的程序展示如下:
//用C语言验证身份证号码对错
#include <stdio.h> /*输入输出函数头文件*/
#include <string.h> /*字符串处理函数头文件*/
int main () //主函数
{ char hm[18]; //定义18位字符串数组:号码hm[]
printf("请连续输入18位身份证号码:");
scanf("%s",hm); //读入身份证号码hm
int dy[11]={1,0,10,9,8,7,6,5,4,3,2,}; //dy为和被11除的余数共有11个:0,1,2,3 …10对应的11位校验码
int xs[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2}; //身份证号码前17位对应的加权系数xs
int i,he=0,ys,jc,jym; //定义循环变量i,及其它变量:和he,余数ys,检查jc,校验码jym
for(i=0;i<=16;i ) {he = (hm[i]-48)*xs[i];} //求加权和
ys = he; //求和被11除的余数
printf("计算出的校验码是:");
if(ys!=2) printf("%d\n",dy[ys]); else printf("x\n"); //输出校验码(因余数2对应的校验码10是两位数,故用罗马数字x表示)
if(hm[17] != 'x') jym=hm[17]-48; else jym=10; //处理校验码
jc=(ys jym); //检查:
if(jc == 1) printf("身份证号码输入正确!"); else printf("身份证号码输入有误!");
}