身份证号码编排规则及校验位C语言C#语言Java语言实现.docx

上传人:b****6 文档编号:7567290 上传时间:2023-01-25 格式:DOCX 页数:17 大小:21.46KB
下载 相关 举报
身份证号码编排规则及校验位C语言C#语言Java语言实现.docx_第1页
第1页 / 共17页
身份证号码编排规则及校验位C语言C#语言Java语言实现.docx_第2页
第2页 / 共17页
身份证号码编排规则及校验位C语言C#语言Java语言实现.docx_第3页
第3页 / 共17页
身份证号码编排规则及校验位C语言C#语言Java语言实现.docx_第4页
第4页 / 共17页
身份证号码编排规则及校验位C语言C#语言Java语言实现.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

身份证号码编排规则及校验位C语言C#语言Java语言实现.docx

《身份证号码编排规则及校验位C语言C#语言Java语言实现.docx》由会员分享,可在线阅读,更多相关《身份证号码编排规则及校验位C语言C#语言Java语言实现.docx(17页珍藏版)》请在冰豆网上搜索。

身份证号码编排规则及校验位C语言C#语言Java语言实现.docx

身份证号码编排规则及校验位C语言C#语言Java语言实现

身份证号码编排规则及校验位C语言、C#语言、Java语言实现

///

///校验身份证号,如果正确返回true如果错误返回false

///

///

/////身份证目前可分为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位的身份证号 

ddddddyymmddxxp 

18位的身份证号 

ddddddyyyymmddxxpy 

其中dddddd为地址码(省地县三级)18位中的和15位中的不完全相同 

yyyymmddyymmdd为出生年月日 

xx顺号类编码 

p性别 

18位中末尾的y为校验码,将前17位的ascii码值经位移、异或运算结果不在0-9的令其为x 

18位身份证标准在国家质量技术监督局于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位置上的加权因子,其各位对应的值依次为:

7910584216379105842 

  2.以11对计算结果取模 

  Y=mod(S,11) 

  3.根据模的值得到对应的校验码 

  对应关系为:

 

  Y值:

012345678910 

  校验码:

10X98765432

1.C语言实现校验:

#include

#include

#include

#include

//C语言实现国民身份证号校验

intIsDigitBuf(char*sBuf,intnLen)

{

inti;

if(nLen==0)return1;

if(nLen>strlen(sBuf))nLen=strlen(sBuf);

for(i=0;i

if(!

isdigit(sBuf[i]))return0;

return1;

}

intcheckdate(intiYear,intiMonth,intiDay)

{

if(iYear<0||iYear>9999)

return-1;

switch(iMonth)

{

case1:

case3:

case5:

case7:

case8:

case10:

case12:

if(iDay<=0||iDay>31)

{

return-3;

}

break;

case4:

case6:

case9:

case11:

if(iDay<=0||iDay>30)

{

return-3;

}

break;

case2:

if((iYear%4==0&&iYear%100!

=0)||iYear%400==0)

{

if(iDay<=0||iDay>29)

{

return-3;

}

}

else

{

if(iDay<=0||iDay>28)

{

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(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");

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(iDate<1900||iDate>2020){

printf("FAIL\n");

exit

(1);

}

memset(sDate,0,sizeof(sDate));

memcpy(sDate,sIdCardNo+6,8);

iRet=CheckStrDate(sDate);

if(iRet<0){

printf("FAIL\n");

exit

(1);

}

/*身份证18位校验位是否有效*/

for(i=0;i<17;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语言实现校验:

package com.haier.hmms.util;  

import java.text.SimpleDateFormat;  

import java.util.Date;  

/** 

 * 验证身份证号码 身份证号码, 可以解析身份证号码的各个字段,以及验证身份证号码是否有效; 身份证号码构成:

6位地址编码+8位生日+3位顺序码+1位校验码 

 *  

 * @ClassName:

 CheckIdCard 

 * @Description:

 TODO 

 * @author suncy 

 * @date 2013-1-4 上午11:

06:

09 

 *  

 */  

public class CheckIdCard {  

 private String cardNumber; // 完整的身份证号码  

 private Boolean cacheValidateResult = null; // 缓存身份证是否有效,因为验证有效性使用频繁且计算复杂  

 private Date cacheBirthDate = null; // 缓存出生日期,因为出生日期使用频繁且计算复杂  

 private final static String BIRTH_DATE_FORMAT = "yyyyMMdd"; // 身份证号码中的出生日期的格式  

 private final static Date MINIMAL_BIRTH_DATE = new Date(-2209017600000L); // 身份证的最小出生日期,1900年1月1日  

 private final static int NEW_CARD_NUMBER_LENGTH = 18;  

 private final static int OLD_CARD_NUMBER_LENGTH = 15;  

 private final static char[] VERIFY_CODE = { '1', '0', 'X', '9', '8', '7',  

   '6', '5', '4', '3', '2' }; // 18位身份证中最后一位校验码  

 private final static int[] VERIFY_CODE_WEIGHT = { 7, 9, 10, 5, 8, 4, 2, 1,  

   6, 3, 7, 9, 10, 5, 8, 4, 2 };// 18位身份证中,各个数字的生成校验码时的权值  

 public boolean validate() {  

  if (null == cacheValidateResult) {  

   boolean result = true;  

   result = result && (null !

= cardNumber); // 身份证号不能为空  

   result = result && NEW_CARD_NUMBER_LENGTH == cardNumber.length(); // 身份证号长度是18(新证)  

   // 身份证号的前17位必须是阿拉伯数字  

   for (int i = 0; result && i < NEW_CARD_NUMBER_LENGTH - 1; i++) {  

    char ch = cardNumber.charAt(i);  

    result = result && ch >= '0' && ch <= '9';  

   }  

   // 身份证号的第18位校验正确  

   result = result  

     && (calculateVerifyCode(cardNumber) == cardNumber  

       .charAt(NEW_CARD_NUMBER_LENGTH - 1));  

   // 出生日期不能晚于当前时间,并且不能早于1900年  

   try {  

    Date birthDate = this.getBirthDate();  

    result = result && null !

= birthDate;  

    result = result && birthDate.before(new Date());  

    result = result && birthDate.after(MINIMAL_BIRTH_DATE);  

    /** 

     * 出生日期中的年、月、日必须正确,比如月份范围是[1,12],日期范围是[1,31],还需要校验闰年、大月、小月的情况时, 

     * 月份和日期相符合 

     */  

    String birthdayPart = this.getBirthDayPart();  

    String realBirthdayPart = this.createBirthDateParser().format(  

      birthDate);  

    result = result && (birthdayPart.equals(realBirthdayPart));  

   } catch (Exception e) {  

    result = false;  

   }  

   cacheValidateResult = Boolean.valueOf(result);// TODO  

               // 完整身份证号码的省市县区检验规则  

  }  

  return cacheValidateResult;  

 }  

 /** 

  * 如果是15位身份证号码,则自动转换为18位 

  *  

  * @param cardNumber 

  * @return  

  */  

 public CheckIdCard(String cardNumber) {  

  if (null !

= cardNumber) {  

   cardNumber = cardNumber.trim();  

   if (OLD_CARD_NUMBER_LENGTH == cardNumber.length()) {  

    cardNumber = contertToNewCardNumber(cardNumber);  

   }  

  }  

  this.cardNumber = cardNumber;  

 }  

 public String getCardNumber() {  

  return cardNumber;  

 }  

 public String getAddressCode() {  

  this.checkIfValid();  

  return this.cardNumber.substring(0, 6);  

 }  

 public Date getBirthDate() {  

  if (null == this.cacheBirthDate) {  

   try {  

    this.cacheBirthDate = this.createBirthDateParser().parse(  

      this.getBirthDayPart());  

   } catch (Exception e) {  

    throw new RuntimeException("身份证的出生日期无效");  

   }  

  }  

  return new Date(this.cacheBirthDate.getTime());  

 }  

 public boolean isMale() {  

  return 1 == this.getGenderCode();  

 }  

 public boolean isFemal() {  

  return false == this.isMale();  

 }  

 /** 

  * 获取身份证的第17位,奇数为男性,偶数为女性 

  *  

  * @return 

  */  

 private int getGenderCode() {  

  this.checkIfValid();  

  char genderCode = this.cardNumber.charAt(NEW_CARD_NUMBER_LENGTH - 2);  

  return (((int) (genderCode - '0')) & 0x1);  

 }  

 private String getBirthDayPart() {  

  return this.cardNumber.substring(6, 14);  

 }  

 private SimpleDateFormat createBirthDateParser() {  

  return new SimpleDateFormat(BIRTH_DATE_FORMAT);  

 }  

 private void checkIfValid() {  

  if (false == this.validate()) {  

   throw new RuntimeException("身份证号码不正确!

");  

  }  

 }  

 /** 

  * 校验码(第十八位数):

 

  *  

  * 十七位数字本体码加权求和公式 S = Sum(Ai * Wi), i = 0...16 ,先对前17位数字的权求和; 

  * Ai:

表示第i位置上的身份证号码数字值 Wi:

表示第i位置上的加权因子 Wi:

 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 

  * 2; 计算模 Y = mod(S, 11)< 通过模得到对应的校验码 Y:

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

 1 0 X 9 

  * 8 7 6 5 4 3 2 

  *  

  * @param cardNumber 

  * @return 

  */  

 private static char calculateVerifyCode(CharSequence cardNumber) {  

  int sum = 0;  

  for (int i = 0; i < NEW_CARD_NUMBER_LENGTH - 1; i++) {  

   char ch = cardNumber.charAt(i);  

   sum += ((int) (ch - '0')) * VERIFY_CODE_WEIGHT[i];  

  }  

  return VERIFY_CODE[sum % 11];  

 }  

 /** 

  * 把15位身份证号码转换到18位身份证号码
 

  * 15位身份证号码与18位身份证号码的区别为:


 

  * 1、15位身份证号码中,"出生年份"字段是2位,转换时需要补入"19",表示20世纪
 

  * 2、15位身份证无最后一位校验码。

18位身份证中,校验码根据根据前17位生成 

  *  

  * @param cardNumber 

  * @return 

  */  

 private static String contertToNewCardNumber(String oldCardNumber) {  

  StringBuilder buf = new StringBuilder(NEW_CARD_NUMBER_LENGTH);  

  buf.append(oldCardNumber.substring(0, 6));  

  buf.append("19");  

  buf.append(oldCardNumber.substring(6));  

  buf.append(CheckIdCard.calculateVerifyCode(buf));  

  return buf.toString();  

 }  

}  

3.C#语言实现校验:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.ComponentModel;

usingSystem.Data;

usingSystem.Drawing;

usingSystem.Linq;

usingSystem.Text;

usingSystem.Windows.Forms;

namespace测试四

{

publicpartialclassForm1:

Form

{

publicForm1()

{

InitializeComponent();

}

privatevoidbtnLook_Click(objectsender,EventArgse)

{

//身份证目前可分为15位和18位

//15位号码组成:

(2)市

(2)区/县

(2)年(

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 面试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1