18位身份证格式是否正确
首先看看身份号码是如何产生的
: 公民身份证号码是特征组合码,由17位数字本体码和一位校验码组成,排列顺序从左到右依次为 6位数字地址码 ,8位数字出生日期码 3位数字顺序码和1位数字校验码
其中顺序码表示的是同一地域范围内对同年同月同日出生的编订的顺序号 顺序码为奇数的分给男性 偶数的分给女性
校验码采用ISO 7064:1983 MOD 11-2校验码系统
校验码的求法:
对前17位数字加权求和 公式为: S=Sum(Ai* Wi); Ai表示第i位的数值 Wi表示第i位的加权因子按照顺序 加权因子分别为
{ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 }
然后对S取模 公式为: Y=mod(S,11); 即让S对11取余得到Y
然后通过Y得到校验码 校验码与Y的对应关系是
{ 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 }
public class IdCard
{
private static final int[] weigh = new int[]
{ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };// 加权因子
private static final int[] checkDigital = new int[]
{ 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 };// 校验码
private String getCheckDigital(String eighteenCardId)//计算身份证的最后一位(校验码)
{
int remain = 0;
if (eighteenCardId.length() == 18)
eighteenCardId = eighteenCardId.substring(0, 17);
if (eighteenCardId.length() == 17)
{
int sum = 0;
Integer[] a = new Integer[17];
for (int i = 0; i < 17; i++)
{
String kString = eighteenCardId.substring(i, i + 1);
a[i] = Integer.parseInt(kString);
}
for (int i = 0; i < 17; i++)
sum += a[i] * weigh[i];
remain = sum % 11;
}
return remain == 2 ? "X" : String.valueOf(checkDigital[remain]);
}
private String updata2eighteen(String fifteen)
{
String eighteenString = fifteen.substring(0, 6);
eighteenString += "19";//15位的身份证中其年份中没有“19”因此要加上19
eighteenString += fifteen.substring(6, 15);
eighteenString += getCheckDigital(eighteenString);
return eighteenString;
}
public boolean verify(String str)
{
if (str.length() == 15)
str = this.updata2eighteen(str);
if (str.length() != 18)
return false;
String last = str.substring(17, 18);
if (last.equals(this.getCheckDigital(str)))
return true;
return false;
}
public static void main(String[] args)
{
String string = "412829199411268016";
IdCard idCard = new IdCard();
if (idCard.verify(string))
System.out.println("合格");
else
System.out.println("不合格");
}
}
梦里不知身是客,一晌贪欢。