疑问

  • 大陆身份证号的规律标准是什么?生成的算法是什么?

小论

310105198605125678

以上海身份证号为例,前六位是地区号码,上海市310,后面的三位是区县代码;接下来的8位是出生年月日,位数不足就补零处理;还剩4位,15位到17位是当天出生的婴儿的顺序号,第17位有特殊含义,奇数是男生,偶数是女生,这三位生成可以当做随机数处理;最后一位,第18位是校验位,根据前面17位计算得出。

ISO 7064:1983.MOD11-2校验码计算法 : (身份证校验码-18位)

假设某一17位数字是

17位数字 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7

加权因子 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2

计算17位数字各位数字与对应的加权因子的乘积的和S: 1×7+2×9+3×10+4×5+5×8+6×4+7×2+8×1+9×6+0×3+1×7+2×9+3×10+4×5+5×8+6×4+7×2=368;

计算S÷11的余数T: 368 mod 11=5;

(( 余数0-10对应校验码为[1, 0, X , 9, 8, 7, 6, 5, 4, 3, 2],算法如下 ))

计算(12-T)÷11的余数R,如果R=10,校验码为字母“X”;如果R≠10,校验码为数字“R”:(12-5)mod 11=7。 该17位数字的校验码就是7,聚合在一为123456789012345677。

实现-IdGen.Java

其他的字符串拼接都没什么,主要是校验码算法的实现calcTrailingNumber()方法

import java.util.*;
public class IdGen {
  public String generate() {
    StringBuilder generater = new StringBuilder();
    generater.append("110101");
    generater.append("20161110");
    generater.append(this.randomCode());
    generater.append(this.calcTrailingNumber(generater.toString().toCharArray()));
    System.out.println("31023019920622745" +" and  "+calcTrailingNumber("31023019920622745".toCharArray()));
    return generater.toString();
  }
  public char calcTrailingNumber(char[] chars) {
    if (chars.length < 17) {
      return ' ';
    }
    int[] c = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
    char[] r = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' };
    int[] n = new int[17];
    int result = 0;
    for (int i = 0; i < n.length; i++) {
      n[i] = Integer.parseInt(chars[i] + "");
    }
    for (int i = 0; i < n.length; i++) {
      result += c[i] * n[i];
    }
    return r[result % 11];
  }
  public String randomCode() {
    int code = (int) (Math.random() * 1000);
    if (code < 10) {
      return "00" + code;
    } else if (code < 100) {
      return "0" + code;
    } else {
      return "" + code;
    }
  }
}

本文作者zhangzj, 欢迎评论、交流。
转载请务必标注出处: 身份证号生成器-Java实现


«Previous:   Java语言整理总集篇

»Next:         MyBatis的配置细节和理解使用