
在中国,按照两个国家标准,即〖GB 11643-1989〗和〖GB 11643-1999〗,目前使用公民号码有两个方面.
其中,“ GB 11643-1989”按从左到右的顺序规定了15位ID号:
6位地址代码,6位出生日期代码,3位顺序代码,出生日期年份为2位,因此无法区分1900和2000. (目前已取消该算法)
在GB 11643-1999中,指定了18位的ID号,而国籍号是功能的组合,由17位的身体代码和1位的验证码组成. 从左到右的顺序是:
6位地址码,8位出生日期码,3位顺序码和1位校验码.
1. 地址代码代表编码对象永久居所所在县(市,州,州,县)的行政区划代码;
2. 出生日期代码代表编码对象的出生年份,月份和日期,其中年份用4位数字表示,并且年份,月份和日期之间没有分隔符;
3. 顺序码表示分配给在同一地址码标识的区域内同一年,月和日出生的人的顺序号. 序列号的奇数分配给男性,偶数分配给女性;
4. 验证码是根据前十七位代码并根据〖ISO 7064: 1983〗.MOD 11-2验证码计算得出的验证码.
首先讨论该校验位的计算.
公式如下:
∑(a [i] * W [i])mod 11(i = 2,3,...,18)
* ---------表示乘法符号
i ---------表示ID编号的每个数字的序列号,从右到左,最左侧为18,最右侧为1.
a [i] ------表示号的第i位数字
W [i] -----表示第i个位置W [i] = 2 ^(i-1)mod 11的权重值
然后让上述∑的总和为R
根据下表找到与R对应的验证码,它是需要ID号的验证码C.
R 0 1 2 3 4 5 6 7 8 9 10
C 1 0 X 9 8 7 6 5 4 3 2
可以看到X代表10,罗马数字10代表X,因此新的标准ID号可能包含非数字字母X.
一个例子来说明:
ID号-输入的ID号
位权重-该值是从公式W [i] = 2 ^(i-1)mod11中得出的,例如,第一位的位权重是7 = Mod(2 ^(18-1) ,11)
加权总和-–∑(a [i] * W [i]),是ID卡第i个位置的数字与第i个位置的权重之和.
代码-加权总和Mod 11对的C值(即校验码)

单击图片以查看大图. 有关详细的计算步骤和公式,请参阅随附文档“ ID Verification Tool.xlsx”的Sheet2.
C语言实现的18位ID号码校验位计算(无需个人验证):
[代码语言=“ c”]
#include
#include
#include
#include
int IsDigitBuf(char * sBuf,int nLen)
{
int i;

如果(nLen == 0)返回1;
if(nLen> strlen(sBuf))nLen = strlen(sBuf);
for(i = 0; i 如果(!isdigit(sBuf [i]))返回0; 返回1; } int checkdate(int iYear,int iMonth,int iDay) { 如果(iYear <0 || iYear> 9999) 返回-1; 切换(iMonth) { 情况1: 情况3: 案例5: 案例7: 案例8: 案例10: 案例12: 如果(iDay <= 0 || iDay> 31) { 返回-3; } 休息; 情况4: 情况6: 案例9: 案例11: 如果(iDay <= 0 || iDay> 30) { 返回-3; } 休息; 情况2: if(((iYear%4 == 0 && iYear%100!= 0)|| iYear%400 == 0) { 如果(iDay <= 0 || iDay> 29) { 返回-3; } } 其他 { 如果(iDay <= 0 || iDay> 28) { 返回-3; } } 休息; 默认值: 返回-2; } 返回0; } int CheckStrDate(字符* sDate) { int iRet; char年份[5]; char sMonth [3]; char sDay [3]; memset(年份,0,sizeof(年份)); 内存集(sMonth,0,sizeof(sMonth)); 内存集(sDay,0,sizeof(sDay)); 如果(strlen(sDate)!= 8) { 返回-1; } memcpy(年份,sDate,4); memcpy(sMonth,sDate + 4,2); memcpy(sDay,sDate + 6、2); iRet =检查日期(atoi(年),atoi(sMonth),atoi(sDay)); 如果(iRet!= 0) { 返回-1; } 返回0; } int main(int argc,char * argv []) { int i; int iRet; int iWeight [18] = {7,9,10,5,8,4,2,1,6,6,7,7,10,5,8,4,2,1}; char cCheck [11] = {'1','0','X','9','8','7','6','5','4','3', '2'}; char sIdCardNo [20]; char sDate [8 +1]; int iDate; int Sum = 0; if(argc <2){printf(“ FAIL \ n”); exit(1);} memset(sIdCardNo,0,20); memcpy(sIdCardNo,argv [1],18); if((strlen(sIdCardNo)== 15)&&((iRet = IsDigitBuf(sIdCardNo,15))> 0)){ printf(“ OK \ n”); 退出(0); }否则,如果(strlen(sIdCardNo)!= 18){ printf(“ FAIL \ n”); 退出(1); } / * ID卡的7-14位有效* / 内存集(sDate,0,sizeof(sDate)); memcpy(sDate,sIdCardNo + 6、4); iDate = atoi(sDate); if(iDate <1900 || iDate> 2020){ printf(“ FAIL \ n”); 退出(1); } 内存集(sDate,0,sizeof(sDate)); memcpy(sDate,sIdCardNo + 6、8); iRet = CheckStrDate(sDate); 如果(iRet <0){ printf(“ FAIL \ n”); 退出(1); } / *的18位校验位是否有效* / for(i = 0; i <17; i ++){ 内存集(sDate,0,sizeof(sDate)); sDate [0] = sIdCardNo [i]; iDate = atoi(sDate); 总和= iWeight [i] * iDate; } 总和= 11; if('x'== sIdCardNo [17]){ sIdCardNo [17] ='X'; } if(cCheck [Sum]!= sIdCardNo [17]){ printf(“ FAIL \ n”); 退出(1); } printf(“ OK \ n”); 退出(0); } [/代码] Excel函数实现 还可以使用excel函数公式来验证ID卡号码,假设要验证的ID卡号码位于单元格B2中. 一个18位号码验证功能公式: [code light =“ true”] = IF(LEN(B2)= 18,IF(MID(“ 10X98765432”,MOD(SUM(MID(LEFT(B2,17),ROW(INDIRECT(“ 1:17”))),1)* 2 ^(18-ROW(INDIRECT(“ 1:17”)))),11)+1,1)= RIGHT(B2,1)号校验位,“通过”,“检查失败”),“”) [/代码] 第二个15位数的号码和18位数的功能公式: [code light =“ true”] = IF(LEN(B2)= 15,REPLACE(B2,7 ,, 19)&MID(“ 10X98765432”,MOD(SUM(MID(REPLACE(B2,7 ,, 19)号校验位,ROW(INDIRECT(“ 1: 17“)),1)* 2 ^(18-ROW(INDIRECT(” 1:17“)))),11)+1,1),”“) [/代码] 三,同时完成15位升序或18位验证的功能公式: [code light =“ true”] = IF(LEN(B2)= 18,IF(MID(“ 10X98765432”,MOD(SUM(MID(LEFT(B2,17),ROW(INDIRECT(“ 1:17”))),1)* 2 ^(18-ROW(INDIRECT(“ 1:17”))))),11)+1,1)= RIGHT(B2,1),“通过”,“检查失败”),IF(LEN(B2)= 15,REPLACE(B2,7 ,, 19)&MID(“ 10X98765432”,MOD(SUM(MID(REPLACE(B2,7 ,, 19),ROW(INDIRECT(“ 1:17”)),1)* 2 ^(18-ROW(INDIRECT(“ 1:17”)))),11)+1,1),“”)) [/代码] 注意: 上式中的B2是ID编号所在的单元格. 这些公式都是数组公式. 输入公式后,按ctrl + shift + Enter结束公式,以便公式在{}括号内即可正确计算. 但是,您不能直接在公式的两边输入{}. 附件列表: 单击此处下载 附件1: 验证码计算器(蝙蝠批处理文件) 附件2: Excel身份验证模型(xlsx文件,Sheet1验证生日,性别等信息和验证码,Sheet2演示了验证码的计算过程,非常详细!) . 参考: [1]号码编码风扇[包括验证工具] [2]号码验证公式_excel功能公式示例 此文章的永久链接: |小谢的小车站

本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-194741-1.html
我们真的倒退100年