Case of Android ID Number Validity Verification Tool

  • 2021-12-05 07:33:27
  • OfStack

I don't remember where I found it. I modified some codes to fix the problem of abnormal time zone format when I used it on Android platform.


package cn.aikongmeng.demo.utils;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

/**
 * Created by Arjun on 2017/4/25.
 *  Validity verification of ID card 
 */

public class IdentityUtils {
  //   Bit weight array 
  private static byte[] Wi = new byte[17];
  //   Number of characters in the front part of ID card 
  private static final byte fPart = 6;
  //   Key value of modulus calculation by ID card algorithm 
  private static final byte fMod = 11;
  //   Length of old ID card 
  private static final byte oldIDLen = 15;
  //   Length of new ID card 
  private static final byte newIDLen = 18;
  //   Year mark of new ID card 
  private static final String yearFlag = "19";
  //   Check code string 
  private static final String CheckCode = "10X98765432";
  //   Minimum administrative division code 
  private static final int minCode = 150000;
  //   Maximum administrative division code 
  private static final int maxCode = 700000;
//   Old ID card number 
//  private String oldIDCard="";
//   New ID card number 
//  private String newIDCard="";
//   Area and code 

  //private String Area[][2] =
  private static void setWiBuffer() {
    for (int i = 0; i < Wi.length; i++) {
      int k = (int) Math.pow(2, (Wi.length - i));
      Wi[i] = (byte) (k % fMod);
    }
  }

  // The last to obtain a new ID card 1 Bit : Check bit 
  private static String getCheckFlag(String idCard) {
    int sum = 0;
    // Perform weighted summation 
    for (int i = 0; i < 17; i++) {
      sum += Integer.parseInt(idCard.substring(i, i + 1)) * Wi[i];
    }
    // Modulus operation to obtain modulus value 
    byte iCode = (byte) (sum % fMod);
    return CheckCode.substring(iCode, iCode + 1);
  }

  // Judge the legitimacy of string length 
  private static boolean checkLength(final String idCard, boolean newIDFlag) {
    boolean right = (idCard.length() == oldIDLen) || (idCard.length() == newIDLen);
    newIDFlag = false;
    if (right) {
      newIDFlag = (idCard.length() == newIDLen);
    }
    return right;
  }

  // Get time string 
  private static String getIDDate(final String idCard, boolean newIDFlag) {
    String dateStr = "";
    if (newIDFlag)
      dateStr = idCard.substring(fPart, fPart + 8);
    else
      dateStr = yearFlag + idCard.substring(fPart, fPart + 6);
    return dateStr;
  }

  // Judge the legitimacy of time 
  private static boolean checkDate(final String dateSource) {
    String dateStr = dateSource.substring(0, 4) + "-" + dateSource.substring(4, 6) + "-" + dateSource.substring(6, 8);
    System.out.println(dateStr);
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    try {
      Date date = df.parse(dateStr);
      return (date != null);
    } catch (java.text.ParseException e) {
      e.printStackTrace();
      return false;
    }
  }

  // Conversion of old ID card to new ID card number 
  public static String getNewIDCard(final String oldIDCard) {
    // Initialization method 
    IdentityUtils.setWiBuffer();
    if (!checkIDCard(oldIDCard)) {
      return oldIDCard;
    }
    String newIDCard = oldIDCard.substring(0, fPart);
    newIDCard += yearFlag;
    newIDCard += oldIDCard.substring(fPart, oldIDCard.length());
    String ch = getCheckFlag(newIDCard);
    newIDCard += ch;
    return newIDCard;
  }

  // Conversion of new ID card to old ID card number 
  public static String getOldIDCard(final String newIDCard) {
    // Initialization method 
    IdentityUtils.setWiBuffer();
    if (!checkIDCard(newIDCard)) {
      return newIDCard;
    }
    String oldIDCard = newIDCard.substring(0, fPart) +
        newIDCard.substring(fPart + yearFlag.length(), newIDCard.length() - 1);
    return oldIDCard;
  }

  // Judge the legality of ID card number 
  public static boolean checkIDCard(final String idCard) {
    // Initialization method 
    IdentityUtils.setWiBuffer();

    int length = idCard.length();
    boolean isNew;
    if (length == oldIDLen) isNew = false;
    else if (length == newIDLen) isNew = true;
    else return false;

    //String message = "";
    if (!checkLength(idCard, isNew)) {
      //message = "ID Abnormal length ";
      return false;
    }
    String idDate = getIDDate(idCard, isNew);
    if (!checkDate(idDate)) {
      //message = "ID Temporal anomaly ";
      return false;
    }
    if (isNew) {
      String checkFlag = getCheckFlag(idCard);
      String theFlag = idCard.substring(idCard.length() - 1, idCard.length());
      if (!checkFlag.equals(theFlag)) {
        //message = " Abnormal check bit of new ID card ";
        return false;
      }
    }
    return true;
  }

  // Get 1 Random " Pseudo " ID card number 
  public static String getRandomIDCard(final boolean idNewID) {
    // Initialization method 
    IdentityUtils.setWiBuffer();
    Random ran = new Random();
    String idCard = getAddressCode(ran) + getRandomDate(ran, idNewID) + getIDOrder(ran);
    if (idNewID) {
      String ch = getCheckFlag(idCard);
      idCard += ch;
    }
    return idCard;
  }

  // Generate random area codes 
  private static String getAddressCode(Random ran) {
    if (ran == null) {
      return "";
    } else {
      int addrCode = minCode + ran.nextInt(maxCode - minCode);
      return Integer.toString(addrCode);
    }
  }

  // Generate random birth dates 
  private static String getRandomDate(Random ran, boolean idNewID) {
    // TODO Auto-generated method stub
    if (ran == null) {
      return "";
    }
    int year = 0;
    if (idNewID) {
      year = 1900 + ran.nextInt(2017 - 1900);
    } else {
      year = 1 + ran.nextInt(99);
    }
    int month = 1 + ran.nextInt(12);
    int day = 0;
    if (month == 2) {
      day = 1 + ran.nextInt(28);
    } else if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
      day = 1 + ran.nextInt(31);
    } else {
      day = 1 + ran.nextInt(30);
    }
    NumberFormat nf = NumberFormat.getIntegerInstance();
    nf.setMaximumIntegerDigits(2);
    nf.setMinimumIntegerDigits(2);
    String dateStr = Integer.toString(year) + nf.format(month) + nf.format(day);
    return dateStr;
  }

  // Generate random serial numbers 
  private static String getIDOrder(Random ran) {
    // TODO Auto-generated method stub
    NumberFormat nf = NumberFormat.getIntegerInstance();
    nf.setMaximumIntegerDigits(3);
    nf.setMinimumIntegerDigits(3);
    if (ran == null) {
      return "";
    } else {
      int order = 1 + ran.nextInt(999);
      return nf.format(order);
    }
  }

  public IdentityUtils() {
    setWiBuffer();
  }

  /**
   * @param args
   */
  public static void main(String[] args) {
    boolean checkFlag = IdentityUtils.checkIDCard("512501197203035172");
    System.out.println(checkFlag);
  }
}

Additional knowledge: Android "ID card verification method" has been encapsulated and can be directly called and available

When doing the project, it is necessary to check the ID card of the user, and it is troublesome to write one alone, so I asked Du Niang for assistance and tried several methods. This method is more comprehensive and practical.

Record this and thank the original author, but now I forget where to copy it


import android.text.TextUtils; 
/**
 * 身份证的工具类
 */
public class IdCardUtil {
 
  private String idCardNum = null; 
  private static int IS_EMPTY = 1;
  private static int LEN_ERROR = 2;
  private static int CHAR_ERROR = 3;
  private static int DATE_ERROR = 4;
  private static int CHECK_BIT_ERROR = 5; 
  private String[] errMsg = new String[]{"身份证完全正确!",
      "身份证为空!",
      "身份证长度不正确!",
      "身份证有非法字符!",
      "身份证中出生日期不合法!",
      "身份证校验位错误!"};
 
  private int error = 0;
 
  /**
   * 构造方法。
   *
   * @param idCardNum
   */
  public IdCardUtil(String idCardNum) {
    // super();
    this.idCardNum = idCardNum.trim();
    if (!TextUtils.isEmpty(this.idCardNum)) {
      this.idCardNum = this.idCardNum.replace("x", "X");
    }
  }
 
  public String getIdCardNum() {
    return idCardNum;
  }
 
  public void setIdCardNum(String idCardNum) {
    this.idCardNum = idCardNum;
    if (!TextUtils.isEmpty(this.idCardNum)) {
      this.idCardNum = this.idCardNum.replace("x", "X");
    }
  }
 
  /**
   * 得到身份证详细错误信息。
   *
   * @return 错误信息。
   */
  public String getErrMsg() {
    return this.errMsg[this.error];
  }
 
  /**
   * 是否为空。
   *
   * @return true: null false: not null;
   */
  public boolean isEmpty() {
    if (this.idCardNum == null)
      return true;
    else
      return this.idCardNum.trim().length() > 0 ? false : true;
  }
 
  /**
   * 身份证长度。
   *
   * @return
   */
  public int getLength() {
    return this.isEmpty() ? 0 : this.idCardNum.length();
  }
 
  /**
   * 身份证长度。
   *
   * @return
   */
  public int getLength(String str) {
    return this.isEmpty() ? 0 : str.length();
  }
 
  /**
   * 是否是15位身份证。
   *
   * @return true: 15位 false:其他。
   */
  public boolean is15() {
    return this.getLength() == 15;
  }
 
  /**
   * 是否是18位身份证。
   *
   * @return true: 18位 false:其他。
   */
  public boolean is18() {
    return this.getLength() == 18;
  }
 
  /**
   * 得到身份证的省份代码。
   *
   * @return 省份代码。
   */
  public String getProvince() {
    return this.isCorrect() == 0 ? this.idCardNum.substring(0, 2) : "";
  }
 
  /**
   * 得到身份证的城市代码。
   *
   * @return 城市代码。
   */
  public String getCity() {
    return this.isCorrect() == 0 ? this.idCardNum.substring(2, 4) : "";
  }
 
  /**
   * 得到身份证的区县代码。
   *
   * @return 区县代码。
   */
  public String getCountry() {
    return this.isCorrect() == 0 ? this.idCardNum.substring(4, 6) : "";
  }
 
  /**
   * 得到身份证的出生年份。
   *
   * @return 出生年份。
   */
  public String getYear() {
    if (this.isCorrect() != 0)
      return "";
 
    if (this.getLength() == 15) {
      return "19" + this.idCardNum.substring(6, 8);
    } else {
      return this.idCardNum.substring(6, 10);
    }
  }
 
  /**
   * 得到身份证的出生月份。
   *
   * @return 出生月份。
   */
  public String getMonth() {
    if (this.isCorrect() != 0)
      return "";
 
    if (this.getLength() == 15) {
      return this.idCardNum.substring(8, 10);
    } else {
      return this.idCardNum.substring(10, 12);
    }
  }
 
  /**
   * 得到身份证的出生日子。
   *
   * @return 出生日期。
   */
  public String getDay() {
    if (this.isCorrect() != 0)
      return "";
 
    if (this.getLength() == 15) {
      return this.idCardNum.substring(10, 12);
    } else {
      return this.idCardNum.substring(12, 14);
    }
  }
 
  /**
   * 得到身份证的出生日期。
   *
   * @return 出生日期。
   */
  public String getBirthday() {
    if (this.isCorrect() != 0)
      return "";
 
    if (this.getLength() == 15) {
      return "19" + this.idCardNum.substring(6, 12);
    } else {
      return this.idCardNum.substring(6, 14);
    }
  }
 
  /**
   * 得到身份证的出生年月。
   *
   * @return 出生年月。
   */
  public String getBirthMonth() {
    return getBirthday().substring(0, 6);
  }
 
  /**
   * 得到身份证的顺序号。
   *
   * @return 顺序号。
   */
  public String getOrder() {
    if (this.isCorrect() != 0)
      return "";
 
    if (this.getLength() == 15) {
      return this.idCardNum.substring(12, 15);
    } else {
      return this.idCardNum.substring(14, 17);
    }
  }
 
  /**
   * 得到性别。
   *
   * @return 性别:1-男 2-女
   */
  public String getSex() {
    if (this.isCorrect() != 0)
      return "";
 
    int p = Integer.parseInt(getOrder());
    if (p % 2 == 1) {
      return "男";
    } else {
      return "女";
    }
  }
 
  /**
   * 得到性别值。
   *
   * @return 性别:1-男 2-女
   */
  public String getSexValue() {
    if (this.isCorrect() != 0)
      return "";
 
    int p = Integer.parseInt(getOrder());
    if (p % 2 == 1) {
      return "1";
    } else {
      return "2";
    }
  }
 
  /**
   * 得到校验位。
   *
   * @return 校验位。
   */
  public String getCheck() {
    if (!this.isLenCorrect())
      return "";
 
    String lastStr = this.idCardNum.substring(this.idCardNum.length() - 1);
    if ("x".equals(lastStr)) {
      lastStr = "X";
    }
    return lastStr;
  }
 
  /**
   * 得到15位身份证。
   *
   * @return 15位身份证。
   */
  public String to15() {
    if (this.isCorrect() != 0)
      return "";
 
    if (this.is15())
      return this.idCardNum;
    else
      return this.idCardNum.substring(0, 6) + this.idCardNum.substring(8, 17);
  }
 
  /**
   * 得到18位身份证。
   *
   * @return 18位身份证。
   */
  public String to18() {
    if (this.isCorrect() != 0)
      return "";
 
    if (this.is18())
      return this.idCardNum;
    else
      return this.idCardNum.substring(0, 6) + "19" + this.idCardNum.substring(6) + this.getCheckBit();
  }
 
  /**
   * 得到18位身份证。
   *
   * @return 18位身份证。
   */
  public static String toNewIdCard(String tempStr) {
    if (tempStr.length() == 18)
      return tempStr.substring(0, 6) + tempStr.substring(8, 17);
    else
      return tempStr.substring(0, 6) + "19" + tempStr.substring(6) + getCheckBit(tempStr);
  } 
  /**
   * 校验身份证是否正确
   *
   * @return 0:正确
   */
  public int isCorrect() {
    if (this.isEmpty()) {
      this.error = IdCardUtil.IS_EMPTY;
      return this.error;
    }
 
    if (!this.isLenCorrect()) {
      this.error = IdCardUtil.LEN_ERROR;
      return this.error;
    }
 
    if (!this.isCharCorrect()) {
      this.error = IdCardUtil.CHAR_ERROR;
      return this.error;
    }
 
    if (!this.isDateCorrect()) {
      this.error = IdCardUtil.DATE_ERROR;
      return this.error;
    }
 
    if (this.is18()) {
      if (!this.getCheck().equals(this.getCheckBit())) {
        this.error = IdCardUtil.CHECK_BIT_ERROR;
        return this.error;
      }
    } 
    return 0;
  } 
 
  private boolean isLenCorrect() {
    return this.is15() || this.is18();
  }
 
  /**
   * 判断身份证中出生日期是否正确。
   *
   * @return
   */
  private boolean isDateCorrect() {
 
    /*非闰年天数*/
    int[] monthDayN = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    /*闰年天数*/
    int[] monthDayL = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
    int month;
    if (this.is15()) {
      month = Integer.parseInt(this.idCardNum.substring(8, 10));
    } else {
      month = Integer.parseInt(this.idCardNum.substring(10, 12));
    }
 
    int day;
    if (this.is15()) {
      day = Integer.parseInt(this.idCardNum.substring(10, 12));
    } else {
      day = Integer.parseInt(this.idCardNum.substring(12, 14));
    }
 
    if (month > 12 || month <= 0) {
      return false;
    }
 
    if (this.isLeapyear()) {
      if (day > monthDayL[month - 1] || day <= 0)
        return false;
    } else {
      if (day > monthDayN[month - 1] || day <= 0)
        return false;
    }
 
    return true;
  }
 
  /**
   * 得到校验位。
   *
   * @return
   */
  private String getCheckBit() {
    if (!this.isLenCorrect())
      return "";
 
    String temp = null;
    if (this.is18())
      temp = this.idCardNum;
    else
      temp = this.idCardNum.substring(0, 6) + "19" + this.idCardNum.substring(6); 
 
    String checkTable[] = new String[]{"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
    int[] wi = new int[]{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1};
    int sum = 0;
 
    for (int i = 0; i < 17; i++) {
      String ch = temp.substring(i, i + 1);
      sum = sum + Integer.parseInt(ch) * wi[i];
    } 
    int y = sum % 11; 
    return checkTable[y];
  } 
 
  /**
   * 得到校验位。
   *
   * @return
   */
  private static String getCheckBit(String str) {
 
    String temp = null;
    if (str.length() == 18)
      temp = str;
    else
      temp = str.substring(0, 6) + "19" + str.substring(6); 
 
    String checkTable[] = new String[]{"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
    int[] wi = new int[]{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1};
    int sum = 0;
 
    for (int i = 0; i < 17; i++) {
      String ch = temp.substring(i, i + 1);
      sum = sum + Integer.parseInt(ch) * wi[i];
    } 
    int y = sum % 11; 
    return checkTable[y];
  } 
 
  /**
   * 身份证号码中是否存在非法字符。
   *
   * @return true: 正确 false:存在非法字符。
   */
  private boolean isCharCorrect() {
    boolean iRet = true;
 
    if (this.isLenCorrect()) {
      byte[] temp = this.idCardNum.getBytes();
 
      if (this.is15()) {
        for (int i = 0; i < temp.length; i++) {
          if (temp[i] < 48 || temp[i] > 57) {
            iRet = false;
            break;
          }
        }
      }
 
      if (this.is18()) {
        for (int i = 0; i < temp.length; i++) {
          if (temp[i] < 48 || temp[i] > 57) {
            if (i == 17 && temp[i] != 88) {
              iRet = false;
              break;
            }
          }
        }
      }
    } else {
      iRet = false;
    }
    return iRet;
  }
 
  /**
   * 判断身份证的出生年份是否未闰年。
   *
   * @return true :闰年 false 平年
   */
  private boolean isLeapyear() {
    String temp;
 
    if (this.is15()) {
      temp = "19" + this.idCardNum.substring(6, 8);
    } else {
      temp = this.idCardNum.substring(6, 10);
    }
 
    int year = Integer.parseInt(temp);
 
    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
      return true;
    else
      return false;
  }
}

It is important that this method can verify "X" and "x".


Related articles: