鱼C论坛

 找回密码
 立即注册
查看: 3515|回复: 3

[技术交流] c++实现18位身份证校验码的计算公式

[复制链接]
发表于 2013-5-22 12:05:29 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
c++实现18位身份证校验码的计算公式,居民身份证的号码是按照国家的标准编制的,由18位组成:前六位为行政区划代码,第七至第十四位为出生日期码,第15至17位为顺序码,第17位代表性别(奇数为男,偶数为女),第18位为校验码。

作为尾号的校验码,是由号码编制单位按统一的公式计算出来的,如果某人的尾号是0-9,都不会出现X,但如果尾号是10,那么就得用X来代替,因为如果用10做尾号,那么此人的身份证就变成了19位,而19位的号码违反了国家标准,并且我国的计算机应用系统也不承认19位的身份证号码。Ⅹ是罗马数字的10,用X来代替10,可以保证公民的身份证符合国家标准。

  (1)十七位数字本体码加权求和公式

       S = Ai * Wi, i = 2, ... , 18
       Y = mod(S, 11)
       i: 表示号码字符从右至左包括校验码字符在内的位置序号
       Ai:表示第i位置上的身份证号码字符值
       Wi:表示第i位置上的加权因子
       i:      18    17    16     15    14    13    12    11    10    9     8     7     6     5    4    3    2    1
       Wi:    7      9     10      5      8      4      2      1      6     3     7     9    10    5    8    4    2    1

(2)Y值对应的校验码字符值:

       Y:            0    1    2    3    4    5    6    7    8    9    10
       校验码: 1     0    X    9    8    7    6    5    4    3     2

试算一个:身份证号是14010519590215222a1
i:      18    17    16     15    14    13    12    11    10    9     8     7     6     5    4    3    2    1
Ai:     1      4      0       1       0     5       1     9      5     9     0     2     1     5    2    2    2    a1
Wi:    7      9     10      5      8      4      2      1      6     3     7     9    10    5    8    4    2    1

根据公式 S = Ai * Wi=7+36+0+5+0+20+2+9+30+27+0+18+10+25+16+8+4=217

217/11=19+8/11
Y = mod(S, 11)=mod(217,11)=8

所以,检验码为4,该人的身份证号为140105195902152224

程序c++

#include <iostream>
using namespace std;

const int factor[] = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };//加权因子
const int checktable[] = { 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 };//校验值对应表
int checkIDinput( char[] );
void checkID( int[], char[] );
int main()
{
    char ID[ 19 ];
    int IDNumber[ 19 ];
    cout << "输入身份证号码:";
    cin  >> ID;   
    while( !checkIDinput( ID ) )  //防止输入过程中位数输入错误   
    {
           cout << "错误ID,重新输入:";
           cout << "输入身份证号码:";
           cin  >> ID;   
    }
   
    for ( int i = 0; i < 18; i ++ )//相当于类型转换
         IDNumber[ i ] = ID[ i ] - 48;
         
   
    checkID( IDNumber, ID );
   
    system( "pause" );
    return 0;
}

int checkIDinput( char ID[] )//检验身份证是否为18位
{
    if ( strlen( ID ) == 18 )//字符串最后一位\0
       return 1;
    else return 0;
}


void checkID( int IDNumber[], char ID[] )
{
     int i = 0;//i为计数
     int checksum = 0;
     for ( ; i < 17; i ++ )
         checksum += IDNumber[ i ] * factor[ i ];
   
     if ( IDNumber[ 17 ] == checktable[ checksum % 11 ] || ( ID[ 17 ] == 'x' && checktable[ checksum % 11 ] == 2 ))       cout << "正确身份证号码\n";
     else cout << "错误身份证号码\n";
}

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-5-22 13:24:04 | 显示全部楼层
强烈支持楼主ing……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-7-11 23:46:30 | 显示全部楼层
if ( IDNumber[ 17 ] == checktable[ checksum % 11 ] || ( ID[ 17 ] == 'x' && checktable[ checksum % 11 ] == 2 ))       cout << "正确身份证号码\n";
     else cout << "错误身份证号码\n";

最后这里应该是 checktable[ checksum % 11 ] == 10 吧。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-7-14 01:33:27 | 显示全部楼层
谢谢楼主分享!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-26 22:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表