Android身份证号有效性校验工具类案例
作者:aikongmeng 时间:2022-02-02 21:07:01
不记得从哪找的了,修改了部分代码,修复在Android平台下使用时,时区时间格式异常的问题。
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.
* 身份证有效性校验
*/
public class IdentityUtils {
// 位权值数组
private static byte[] Wi = new byte[17];
// 身份证前部分字符数
private static final byte fPart = 6;
// 身份证算法求模关键值
private static final byte fMod = 11;
// 旧身份证长度
private static final byte oldIDLen = 15;
// 新身份证长度
private static final byte newIDLen = 18;
// 新身份证年份标志
private static final String yearFlag = "19";
// 校验码串
private static final String CheckCode = "10X98765432";
// 最小的行政区划码
private static final int minCode = 150000;
// 最大的行政区划码
private static final int maxCode = 700000;
// 旧身份证号码
// private String oldIDCard="";
// 新身份证号码
// private String newIDCard="";
// 地区及编码
//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);
}
}
//获取新身份证的最后一位:检验位
private static String getCheckFlag(String idCard) {
int sum = 0;
//进行加权求和
for (int i = 0; i < 17; i++) {
sum += Integer.parseInt(idCard.substring(i, i + 1)) * Wi[i];
}
//取模运算,得到模值
byte iCode = (byte) (sum % fMod);
return CheckCode.substring(iCode, iCode + 1);
}
//判断串长度的合法性
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;
}
//获取时间串
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;
}
//判断时间合法性
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;
}
}
//旧身份证转换成新身份证号码
public static String getNewIDCard(final String oldIDCard) {
//初始化方法
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;
}
//新身份证转换成旧身份证号码
public static String getOldIDCard(final String newIDCard) {
//初始化方法
IdentityUtils.setWiBuffer();
if (!checkIDCard(newIDCard)) {
return newIDCard;
}
String oldIDCard = newIDCard.substring(0, fPart) +
newIDCard.substring(fPart + yearFlag.length(), newIDCard.length() - 1);
return oldIDCard;
}
//判断身份证号码的合法性
public static boolean checkIDCard(final String idCard) {
//初始化方法
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长度异常";
return false;
}
String idDate = getIDDate(idCard, isNew);
if (!checkDate(idDate)) {
//message = "ID时间异常";
return false;
}
if (isNew) {
String checkFlag = getCheckFlag(idCard);
String theFlag = idCard.substring(idCard.length() - 1, idCard.length());
if (!checkFlag.equals(theFlag)) {
//message = "新身份证校验位异常";
return false;
}
}
return true;
}
//获取一个随机的"伪"身份证号码
public static String getRandomIDCard(final boolean idNewID) {
//初始化方法
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;
}
//产生随机的地区编码
private static String getAddressCode(Random ran) {
if (ran == null) {
return "";
} else {
int addrCode = minCode + ran.nextInt(maxCode - minCode);
return Integer.toString(addrCode);
}
}
//产生随机的出生日期
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;
}
//产生随机的序列号
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);
}
}
补充知识:Android 【身份证校验方法】已封装 可以直接调用 可用
做项目的时候,有需要对用户进行身份证进行校验,苦于单独写一个比较麻烦,于是找度娘协助,试了几个方法这个方法比较全面一些,比较实用。
记录下这个,也感谢原作者,只是现在忘了在哪复制了
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;
}
}
重要的是这个方法可以验证"X","x"。
来源:https://blog.csdn.net/aikongmeng/article/details/70823464
标签:Android,身份证号,校验
0
投稿
猜你喜欢
Android自定义view实现输入控件
2022-12-11 10:08:06
浅析Java中Apache BeanUtils和Spring BeanUtils的用法
2021-07-10 21:29:15
Java线程生命周期的终止与复位
2022-04-22 01:57:01
Spring @Transactional注解失效解决方案
2022-10-25 05:30:30
Android自定义View模仿即刻点赞数字切换效果实例
2023-08-26 12:45:39
android多开器解析与检测实现方法示例
2022-04-01 11:43:15
Android实现实时通信示例
2022-12-27 00:59:55
Android仿UC浏览器左右上下滚动功能
2023-08-27 12:43:19
Java TCP网络通信协议详细讲解
2022-09-26 09:04:22
Maven pom.xml与settings.xml详解
2022-10-12 19:48:41
揭秘在ListView等AdapterView上动态添加删除项的陷阱
2022-11-26 16:02:27
c#异步操作async await状态机的总结(推荐)
2021-08-22 07:13:12
利用thrift实现js与C#通讯的实例代码
2022-09-07 15:49:13
Android搜索框组件SearchView的基本使用方法
2023-01-01 15:37:51
C#数据绑定(DataBinding)简单实现方法
2021-10-09 21:13:22
Android编程实现类似天气预报图文字幕垂直滚动效果的方法
2022-08-02 08:16:50
Android编程之手机壁纸WallPaper设置方法示例
2023-09-27 20:51:10
Java基础教程之理解Annotation详细介绍
2022-02-28 10:07:12
spring cloud整合ribbon问题及解决方案
2023-07-25 04:24:49
C# winform 模拟键盘输入自动接入访问网络的实例
2022-01-01 19:20:10