1. 中国公民身份证常识:
我国现行使用公民身份证号码有两种尊循两个国家标准,〖GB 11643-1989〗和〖GB 11643-1999〗。
〖GB 11643-1989〗中规定的是15位身份证号码:排列顺序从左至右依次为:六位数字地址码,六位数字出生日期码,三位数字顺序码,其中出生日期码不包含世纪数。
6位行政区划分代码 | 6位出生日期 | 3位顺序码 |
|
〖GB 11643-1999〗中规定的是18位身份证号码:公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
6位行政区划分代码 | 6位出生日期 | 3位顺序码 | 1位校验码 |
行政区划分代码:表示编码对象常住户口所在县(市、旗、区)的行政区划代码。
出生日期码:表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。
顺序码:表示同一地址码所标识的区域范围内,对同年、同月、同日出生的人员编定的顺序号。顺序码的奇数分给男性,偶数分给女性。
校验码:是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。
ISO 7064:1983.MOD 11-2校验码计算法
按照中华人民共和国国家标准GB11643-1999规定中华人民共和国公民身份号码校验码的计算方法即为ISO 7064:1983.MOD 11-2校验码计算法。
假设某一17位数字是
17位数字 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
加权因子 | 2 | 4 | 8 | 5 | 10 | 9 | 7 | 3 | 6 | 1 | 2 | 4 | 8 | 5 | 10 | 9 | 7 |
- 计算17位数字各位数字与对应的加权因子的乘积的和S:1×2+2×4+3×8+4×5+5×10+6×9+7×7+8×3+9×6+0×1+1×2+2×4+3×8+4×5+5×10+6×9+7×7=492;
- 计算S÷11的余数T:492 mod 11=8;
- 计算(12-T)÷11的余数R,如果R=10,校验码为字母“X”;如果R≠10,校验码为数字“R”:(12-8)mod 11=4。
该17位数字的校验码就是4,聚合在一为123456789012345674。
package id_card;
import string_util.StringUtil;
/**
* 身份证号码验证小程序
* @author Kevin
* 2010-3-28
*/
public class IdCardUtil {
/** 旧身份证号码位数(完全有数字组成) */
public static final int OLD_IDCARD_LEN=15;
/** 新身份证号码位数 */
public static final int NEW_IDCARD_LEN=18;
/** 存放位权值数组 */
private static int[] wi=new int[17];
/**最小行政区划分代码*/
private final static int MINCODE = 110000;
/**最大行政区划分代码*/
private final static int MAXCODE = 820000;
/** 求模参数 */
private final static int MODE=11;
/** 新身份证年份标记 */
private final static String YEAR_FLAG="19";
/**
* 设置位权值
*/
private static void setWiValue(){
for(int i=0;i<wi.length;i++){
int k=(int)Math.pow(2, (wi.length-i));
wi[i]=k%MODE;
}
}
/**
* 依据新身份证号码前17为数字,得到最后一位验证码
* @param checkString
* @return
*/
private static String getCheckCode(String checkString){
int sum=0;
setWiValue();//设置位权值
for(int i=0;i<checkString.length();i++){
int k=StringUtil.convertInteger(String.valueOf(checkString.charAt(i)))*wi[i];
sum+=k;
}
int num=(12-(sum%MODE))%MODE;
if(num==10){
return "X";
}else{
return String.valueOf(num);
}
}
/**
* 验证身份证号码行政区划分代码是否有效
* @param idCard
* @return
*/
public static boolean isValidateCantonCode(String idCard) throws Exception{
String cantonCode=idCard.substring(0,6);
int code=StringUtil.convertInteger(cantonCode);
if(code>=MINCODE && code<=MAXCODE){
return true;
}
return false;
}
/**
* 验证新身份证最后一位是否有效
* @param lastLetter
* @return
*/
private static boolean isValidateLastCode(String lastCode){
//是否是数字、'x'或'X'
if(StringUtil.isCompleteNumberString(lastCode)||lastCode.equalsIgnoreCase("x")){
return true;
}
return false;
}
/**
* 验证身份证是否有效
* @param idCard
* @return
*/
public static boolean isValidateIdCard(String idCard) throws Exception{
//验证是否是过有效字符串
if(!StringUtil.isValidateString(idCard)){
return false;
}
//去除前后空格
idCard=idCard.trim();
//验证身份证号码是不是15位或18位
if(idCard.length()!=OLD_IDCARD_LEN && idCard.length()!=NEW_IDCARD_LEN){
return false;
}
//验证身份证号码行政区划分代码是否有效
if(!isValidateCantonCode(idCard)){
return false;
}
//身份证生日号码
String birthday="";
if(idCard.length()==OLD_IDCARD_LEN){
if(StringUtil.isCompleteNumberString(idCard)){
birthday=YEAR_FLAG+idCard.substring(6,12);
}
}else{
if(StringUtil.isCompleteNumberString(idCard.substring(0,17))){
if(isValidateLastCode(idCard.substring(17, idCard.length()))){
birthday=idCard.substring(6, 14);
}
}
}
//验证生日日期格式是否有效
if(!StringUtil.isValidateDateString(birthday, "yyyyMMdd")){
return false;
}
//验证新身份证最后一位是否有效
if(idCard.length()==NEW_IDCARD_LEN){
String lastCode=getCheckCode(idCard.substring(0,17));
if(!(String.valueOf(idCard.charAt(17)).equalsIgnoreCase(lastCode))){
return false;
}
}
return true;
}
/**
* 将旧身份证号码转化为新身份证号码
* @param code
* @return
* @throws Exception
*/
public static String oldCard2newCarid(String oldIdCard) throws Exception{
if(!StringUtil.isValidateString(oldIdCard)){
return "";
}
oldIdCard=oldIdCard.trim();
if(oldIdCard.length()!=OLD_IDCARD_LEN||!isValidateIdCard(oldIdCard)){
return "";
}
oldIdCard=oldIdCard.substring(0,6)+YEAR_FLAG+oldIdCard.substring(6);
oldIdCard=oldIdCard+getCheckCode(oldIdCard);
return oldIdCard;
}
/**
* 测试
* @param args
* @throws Exception
*/
public static void main(String args[]) throws Exception{
System.out.println(IdCardUtil.isValidateIdCard("000000000000000000"));
}
}
package string_util;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public final class StringUtil{
/**
* 字符串数组合并
* @param stringAry 字符串数组
* @param joinToken 分隔符
* @return 合并后的字符串
*/
public static String join(String []stringAry,String joinToken){
if(stringAry==null||stringAry.length<=0){
return null;
}
if(joinToken==null||joinToken.equalsIgnoreCase("null")){
joinToken="";
}
joinToken=joinToken.trim();
StringBuffer sb=new StringBuffer();
for(int i=0;i<stringAry.length;i++){
if(i>0){
sb.append(joinToken);
}
sb.append(stringAry[i]);
}
return sb.toString();
}
/**
* 将整数字符串转化为整数
* @param str 数字字符串
* @return 转化后的Int类型
* @throws NumberFormatException
*/
public static int convertInteger(String str) throws NumberFormatException{
int number=0;
if(!isValidateString(str)){
return number;
}
str=str.trim();
try {
number=Integer.parseInt(str);
} catch (NumberFormatException e) {
throw e;
}
return number;
}
/**
* 将浮点数的字符串转化为浮点数
* @param str 要转化的字符串
* @return 转化后的浮点数
* @throws NumberFormatException
*/
public static float convertFloat(String str)throws NumberFormatException{
float number=0.0f;
if(!isValidateString(str)){
return number;
}
str=str.trim();
try {
number=Float.parseFloat(str);
} catch (NumberFormatException e) {
throw e;
}
return number;
}
/**
* 将双精度浮点数的字符串转化为双精度浮点数
* @param str 要转化的字符串
* @return 转化后的值
* @throws NumberFormatException
*/
public static double convertDouble(String str)throws NumberFormatException{
double number=0.0;
if(!isValidateString(str)){
return number;
}
str=str.trim();
try {
number=Double.parseDouble(str);
} catch (NumberFormatException e) {
throw e;
}
return number;
}
/**
* 验证字符串合法性(即该字符串不可以为null)
* 该方法不除去字符串中空格
* @param str String
* @return 如果为空就返回""
*/
public static String CheckString(String str){
if(str==null||str.equalsIgnoreCase("null")){
return "";
}
/**
* 除去前后的空格
*/
return str.trim();
}
/**
* 验证字符串合法性(该字符串可以为null)
* 该方法不除去字符串中空格
* @param str String
* @return 如果为空就返回""
*/
public static String ValidateString(String str){
if(str==null){
return "";
}
/**
* 除去前后的空格
*/
return str.trim();
}
/**
* 验证是否是个有效字符串
* @param str
* @return
*/
public static boolean isValidateString(String str){
if(str==null){
return false;
}
if(str.trim().equals("")){
return false;
}
if(str.equalsIgnoreCase("null")){
return false;
}
return true;
}
/**
* 从当前字符串中某个字符开始截取字符串
* @param str String
* @param singleChar String字符标记
* @param front boolean 如果值为true表式截取标记字符前面的字符,反之相反
* @return 截取后字符串
*/
public static String cutString(String str,String singleChar,boolean front){
if(!isValidateString(str)){
return "";
}
if(!isValidateString(singleChar)){
return "";
}
str=str.trim();
singleChar=singleChar.trim();
if(str.contains(singleChar)){
int index=str.indexOf(singleChar);
if(front){
return str.substring(0,index);
}else{
return str.substring(index+1,str.length());
}
}else{
return str;
}
}
/**
* 将数据库中取出以字符串形式表示的日期
* 转化为:1999-09-09日期格式形式
* @param dbStr String
* @return String 转化后的字符串
*/
public static String toDateString(String dbStr){
if(!isValidateString(dbStr)){
return "";
}
dbStr=dbStr.trim();
return dbStr.substring(0,10);
}
/**
* 将字符串一个字母转换为大写
* @param name
* @return
*/
public static String toUpperCaseFirstLetter(String name){
if(!isValidateString(name)){
return "";
}
name=name.trim();
if(name.length()>0){
return name.substring(0,1).toUpperCase()+name.substring(1);
}
return "";
}
/**
* 将JavaBean属性名转化为其set和get方法名称
* 其转化规则如下:(1)属性名的第二个字母若为大写则不用将首字母转换为大写
* @param prppertyName
* @return
*/
public static String toJavaBeanPropertyForSetOrGetMethodName(String propertyName){
if(!isValidateString(propertyName)){
return "";
}
propertyName=propertyName.trim();
if(propertyName.length()<=1){
return propertyName.toUpperCase();
}else{
char secondLetter=propertyName.charAt(1);
if(secondLetter>='A'&& secondLetter<='Z'){
return propertyName;
}else{
return toUpperCaseFirstLetter(propertyName);
}
}
}
/**
* 将日期字符串转换为日期对象
* @param dateString
* @return
* @throws ParseException
*/
public static Date toStringForDate(String dateString) throws Exception{
Date date=null;
if(!isValidateString(dateString)){
throw new Exception("非日期格式字符串");
}
dateString=dateString.trim();
DateFormat format=DateFormat.getDateInstance();
try {
date=format.parse(dateString);
} catch (ParseException e) {
throw e;
}
return date;
}
/**
* 验证字符串是不是完全有数字和小数点组成
* 此方法还不可以验证16进制和八进制的数据
* @param number
* @return
*/
public static boolean isNumberString(String number){
if(!isValidateString(number)){
return false;
}
number=number.trim();
char[] nums=number.toCharArray();
for(int i=0;i<nums.length;i++){
if((nums[i]>='0'&& nums[i]<='9')||(nums[i]=='.')){
continue;
}else{
return false;
}
}
return true;
}
/**
* 验证字符串是不是完全有数字组成
* @param number
* @return
*/
public static boolean isCompleteNumberString(String number){
if(!isValidateString(number)){
return false;
}
number=number.trim();
char[] nums=number.toCharArray();
for(int i=0;i<nums.length;i++){
if((nums[i]<'0'|| nums[i]>'9')){
return false;
}
}
return true;
}
/**
* 验证日期格式字符串是否和指定样式匹配
* @param date
* @param style 指定样式
* @return
* @throws Exception
*/
public static boolean isValidateDateString(String dateStr,String style) throws Exception{
if(!isValidateString(style)){
return false;
}
if(!isValidateString(dateStr)){
return false;
}
Date date=null;
try{
SimpleDateFormat sdf=new SimpleDateFormat(style);
date =sdf.parse(dateStr);
}catch(Exception e){
throw e;
}
if(date==null){
return false;
}
return true;
}
/**
* 测试方法
* @param args
* @throws Exception
*/
public static void main(String args[]) throws Exception{
// System.out.println(StringUtil.toJavaBeanPropertyForSetOrGetMethodName("aBc"));
if(StringUtil.isValidateDateString("19860912","yyyyMMdd")){
System.out.println("yes");
}else{
System.out.println("no");
}
}
}