根据〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
地址码表示编码对象常住户口所在县(市、旗、区)的行政区划代码。生日期码表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。顺序码表示同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。顺序码的奇数分给男性,偶数分给女性。校验码是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。下面举例说明该计算方法。
ISO 7064:1983 标准(mod 11-2):
7,9,10,5,8,4,2,1,6,3是10个循环的权值,
对前17个数字使用就成了 7,9,10,5,8,4,2,1,6,3 7,9,10,5,8,4,2,(1,6,3)
每一个数字加权和对11取模后用下表(一个反相错位表)转换就可以算出来
0 1 2 3 4 5 6 7 8 9 10
1 0 X 9 8 7 6 5 4 3 2 (X=10)
下面举例说明该计算方法,来验证身份证最后一位校验位是否正确。
某男性公民身份号码本体码为34052419800101001X,首先按照公式⑴计算:
∑(ai×Wi)(mod 11)……………………………………(1)
公式(1)中:
i----表示号码字符从由至左包括校验码在内的位置序号;
ai----表示第i位置上的号码字符值;
Wi----示第i位置上的加权因子,其数值依据公式Wi=2(n-1)(mod 11)计算得出。
i 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
ai 3 4 0 5 2 4 1 9 8 0 0 1 0 1 0 0 1 a1
Wi 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1
ai×Wi 21 36 0 25 16 16 2 9 48 0 0 9 0 5 0 0 2 a1
根据公式(1)进行计算:
∑(ai×Wi) =(21+36+0+25+16+16+2+9+48++0+0+9+0+5+0+0+2) = 189
189 ÷ 11 = 17 + 2/11
∑(ai×Wi)(mod 11) = 2
然后根据计算的结果,从下面的表中查出相应的校验码,其中X表示计算结果为10:
∑(ai×WI)(mod 11) 0 1 2 3 4 5 6 7 8 9 10
校验码字符值ai 1 0 X 9 8 7 6 5 4 3 2
根据上表,查出计算结果为2的校验码为X,所以该人员的公民身份号码应该为 34052419800101001X,是正确的。
一下是 C 的代码示例:
bool validateIDcard(char tmpStr[])
{
int W[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
char A[11]={'1','0','x','9','8','7','6','5','4','3','2'};
long sum;
int i;
sum=0;
for(i=0;i<17;i++)
{
sum = sum + W[i] * (tmpStr[i] - 0x30);
}
sum = sum%11;
if(A[sum]==tmpStr[17])
{
return true;
}
else
{
return false;
}
}
贴一段我写的代码给你吧 VC的,自己看算法吧
void CIDCard_VerifyDlg::OnVerify()
{
// TODO: Add your control notification handler code here
CString strValue = "1234567890X";
CString strTemp;
int nCompute1 = 0,nCompute2 = 0;
UpdateData();
if(m_InputIDCard.IsEmpty() || (m_InputIDCard.GetLength() != 18))
{
AfxMessageBox("身份证号输入无效,请重新输入(身份证号输入为空,或者18位)");
GetDlgItem(IDC_INPUTIDCard)->SetFocus();
return;
}
if(m_InputIDCard.GetLength() > 15)
{
strTemp = m_InputIDCard.Right(1);
nCompute1 = atoi(m_InputIDCard.Mid(1,1)) * 7
+ atoi(m_InputIDCard.Mid(2,1)) * 9
+ atoi(m_InputIDCard.Mid(3,1)) * 10
+ atoi(m_InputIDCard.Mid(4,1)) * 5
+ atoi(m_InputIDCard.Mid(5,1)) * 8
+ atoi(m_InputIDCard.Mid(6,1)) * 4
+ atoi(m_InputIDCard.Mid(7,1)) * 2
+ atoi(m_InputIDCard.Mid(8,1)) * 1
+ atoi(m_InputIDCard.Mid(9,1)) * 6
+ atoi(m_InputIDCard.Mid(10,1)) * 3
+ atoi(m_InputIDCard.Mid(11,1)) * 7
+ atoi(m_InputIDCard.Mid(12,1)) * 9
+ atoi(m_InputIDCard.Mid(13,1)) * 10
+ atoi(m_InputIDCard.Mid(14,1)) * 5
+ atoi(m_InputIDCard.Mid(15,1)) * 8
+ atoi(m_InputIDCard.Mid(16,1)) * 4
+ atoi(m_InputIDCard.Mid(17,1)) * 2;
nCompute2 = nCompute1%11;
if(strValue.Mid(nCompute2+1,1)!=strTemp)
{
//AfxMessageBox(strTemp+ "," + strValue.Mid(nCompute2+1,1));
AfxMessageBox("身份证号输入无效,请重新输入");
}
else
{
AfxMessageBox(m_InputIDCard + "校验通过");
}
}
}