您好,欢迎访问三七文档
当前位置:首页 > 办公文档 > 模板/表格 > 身份证号码编排规则及校验位C语言、C#语言、Java语言实现
身份证号码编排规则及校验位C语言、C#语言、Java语言实现///summary///校验身份证号,如果正确返回true如果错误返回false////summary///paramname=id/////身份证目前可分为15位和18位//15位号码组成:省(2)市(2)区/县(2)年(2)月(2)日(2)+序列号(3)[奇数分配给男性偶数分配给女性]//15位升级到18位:出生年都加上19,第二点:第十八位为校验位,也就是说第十八位要从前17位计算而来//如果是15位数字,那么我们就取得17,8位时出生年//如果是18位,则先校验用户输入的身份证是否合法,如果合法者去7-10位为出生年身份证号码中这些数字是怎样排列的,每个数字表示什么意思呢?下面就让我们一起来探索其中的规律吧!新的身份证号码是由18位数字组成的,它们分别表示:(1)前1、2位数字表示:所在省份的代码;(2)第3、4位数字表示:所在城市的代码;(3)第5、6位数字表示:所在区县的代码;(4)第7~14位数字表示:出生年、月、日;(5)第15、16位数字表示:所在地的派出所的代码;(6)第17位数字表示性别:奇数表示男性,偶数表示女性;(7)第18位数字是校检码:也有的说是个人信息码,一般是随计算机的随机产生,用来检验身份证的正确性。校检码可以是0~9的数字,有时也用x表示。15位的身份证号ddddddyymmddxxp18位的身份证号ddddddyyyymmddxxpy其中dddddd为地址码(省地县三级)18位中的和15位中的不完全相同yyyymmddyymmdd为出生年月日xx顺号类编码p性别18位中末尾的y为校验码,将前17位的ascii码值经位移、异或运算结果不在0-9的令其为x18位身份证标准在国家质量技术监督局于1999年7月1日实施的GB11643-1999《公民身份号码》中做了明确规定。GB11643-1999《公民身份号码》为GB11643-1989《社会保障号码》的修订版,其中指出将原标准名称“社会保障号码”更名为“公民身份号码”,另外GB11643-1999《公民身份号码》从实施之日起代替GB11643-1989。公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位校验码。其含义如下:1.地址码:表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。2.出生日期码:表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日分别用4位、2位、2位数字表示,之间不用分隔符。3.顺序码:表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。校验的计算方式:1.对前17位数字本体码加权求和公式为:S=Sum(Ai*Wi),i=0,...,16其中Ai表示第i位置上的身份证号码数字值,Wi表示第i位置上的加权因子,其各位对应的值依次为:79105842163791058422.以11对计算结果取模Y=mod(S,11)3.根据模的值得到对应的校验码对应关系为:Y值:012345678910校验码:10X987654321.C语言实现校验:#includestdio.h#includestring.h#includemath.h#includetime.h//C语言实现国民身份证号校验intIsDigitBuf(char*sBuf,intnLen){inti;if(nLen==0)return1;if(nLenstrlen(sBuf))nLen=strlen(sBuf);for(i=0;inLen;i++)if(!isdigit(sBuf[i]))return0;return1;}intcheckdate(intiYear,intiMonth,intiDay){if(iYear0||iYear9999)return-1;switch(iMonth){case1:case3:case5:case7:case8:case10:case12:if(iDay=0||iDay31){return-3;}break;case4:case6:case9:case11:if(iDay=0||iDay30){return-3;}break;case2:if((iYear%4==0&&iYear%100!=0)||iYear%400==0){if(iDay=0||iDay29){return-3;}}else{if(iDay=0||iDay28){return-3;}}break;default:return-2;}return0;}intCheckStrDate(char*sDate){intiRet;charsYear[5];charsMonth[3];charsDay[3];memset(sYear,0,sizeof(sYear));memset(sMonth,0,sizeof(sMonth));memset(sDay,0,sizeof(sDay));if(strlen(sDate)!=8){return-1;}memcpy(sYear,sDate,4);memcpy(sMonth,sDate+4,2);memcpy(sDay,sDate+6,2);iRet=checkdate(atoi(sYear),atoi(sMonth),atoi(sDay));if(iRet!=0){return-1;}return0;}intmain(intargc,char*argv[]){inti;intiRet;intiWeight[18]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,1};charcCheck[11]={'1','0','X','9','8','7','6','5','4','3','2'};charsIdCardNo[20];charsDate[8+1];intiDate;intSum=0;if(argc2){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);exit(0);}elseif(strlen(sIdCardNo)!=18){printf(FAIL\n);exit(1);}/*身份证7-14位是否有效*/memset(sDate,0,sizeof(sDate));memcpy(sDate,sIdCardNo+6,4);iDate=atoi(sDate);if(iDate1900||iDate2020){printf(FAIL\n);exit(1);}memset(sDate,0,sizeof(sDate));memcpy(sDate,sIdCardNo+6,8);iRet=CheckStrDate(sDate);if(iRet0){printf(FAIL\n);exit(1);}/*身份证18位校验位是否有效*/for(i=0;i17;i++){memset(sDate,0,sizeof(sDate));sDate[0]=sIdCardNo[i];iDate=atoi(sDate);Sum+=iWeight[i]*iDate;}Sum%=11;if('x'==sIdCardNo[17]){sIdCardNo[17]='X';}if(cCheck[Sum]!=sIdCardNo[17]){printf(FAIL\n);exit(1);}printf(OK\n);exit(0);}2.Java语言实现校验:packagecom.haier.hmms.util;importjava.text.SimpleDateFormat;importjava.util.Date;/***验证身份证号码身份证号码,可以解析身份证号码的各个字段,以及验证身份证号码是否有效;身份证号码构成:6位地址编码+8位生日+3位顺序码+1位校验码**@ClassName:CheckIdCard*@Description:TODO*@authorsuncy*@date2013-1-4上午11:06:09**/publicclassCheckIdCard{privateStringcardNumber;//完整的身份证号码privateBooleancacheValidateResult=null;//缓存身份证是否有效,因为验证有效性使用频繁且计算复杂privateDatecacheBirthDate=null;//缓存出生日期,因为出生日期使用频繁且计算复杂privatefinalstaticStringBIRTH_DATE_FORMAT=yyyyMMdd;//身份证号码中的出生日期的格式privatefinalstaticDateMINIMAL_BIRTH_DATE=newDate(-2209017600000L);//身份证的最小出生日期,1900年1月1日privatefinalstaticintNEW_CARD_NUMBER_LENGTH=18;privatefinalstaticintOLD_CARD_NUMBER_LENGTH=15;privatefinalstaticchar[]VERIFY_CODE={'1','0','X','9','8','7','6','5','4','3','2'};//18位身份证中最后一位校验码privatefinalstaticint[]VERIFY_CODE_WEIGHT={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};//18位身份证中,各个数字的生成校验码时的权值publicbooleanvalidate(){if(null==cacheValidateResult){booleanresult=true;result=result&&(null!=cardNumber);//身份证号不能为空result=result&&NEW_CARD_NUMBER_LENGTH==cardNumber.length();//身份证号长度是18(新证)//身份证号的前17位必须是阿拉伯数字for(inti=0;result&&iNEW_CARD_NUMBER_LENGTH-1;i++){charch=cardNumber.charAt(i);result=result&&ch='0'&&ch='9';}//身份证号的第18位校验正确result=result&&(calculateVerifyCode(cardNumber)==cardNumber.charAt(NEW_CARD_NUMBER_LENGTH-1));//出生日期不能晚于当前时间,并且不能早于1900年try{DatebirthDate=this.getBirthDate();result=result&&null!=birthDate;result=result&&birthDate.before(newDate());result=result&&birthDate.after(MINIMAL_BIRTH_DATE);/***出生日期中的年、月、日必须正确,比如月份范围是[1,12],日期范围是[1,31],还需要校验闰年、大月、小月的情况时,*月份和日期相符合*/StringbirthdayPart=this.getBirthDayPart();StringrealBirthdayPart=this.createBirthDateParser().format(birthDate);resul
本文标题:身份证号码编排规则及校验位C语言、C#语言、Java语言实现
链接地址:https://www.777doc.com/doc-3389830 .html