身份证校验,非正则校验,身份证算法校验。(标签校验 或者方法校验)

身份证校验标签校验

使用需要 @Valid beanxx

还需要引入lombok 包


 

使用方式

package com.xxx.xxx.vo;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.validator.constraints.NotBlank;

import com.cfam.annotations.IDCARD;

/**
* <p>Title: ElectronTagBenaReq.java</p>
* <p>Description: </p>
* @author ken chen
* @date 2019年8月22日
* @version 1.0
*/
@Getter
@Setter
@ToString
public class ElectronTagBenaReq {

    @NotBlank(message="请输入用户名")
    private String userName;

    @NotBlank(message="请输入手机号")
    private String phone;

    @NotBlank(message="请输入银行卡号")
    private String bankId;
    
    @NotBlank(message="请输入身份证号")
    //使用方式加这个注解
        @IDCARD
    private String idcard;

    @NotBlank(message="customerId 失效")
    private String customerId;

    //手机端 标识
    private String resource;
}
    
View Code

身份证校验入口

package com.xxx.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

import com.xxx.xxx.IdCardValidator;


/**
* <p>Title: interfacea.java</p>
* <p>Description: 自定义注解类</p>
* @author ken chen
* @date 2019年5月10日
* @version 1.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE ,ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER })
@Inherited
@Documented
@Constraint(validatedBy = IdCardValidator.class)
public @interface IDCARD {
    String message() default "身份证不正确,请核对后重新填写";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
View Code

身份证实现类

package com.xxx.validator;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import com.xxx.annotations.IDCARD;
import com.xxx.xxx.IsValidIdCard;
import com.xxx.xxx.IsValidldCardInterface;
import com.xxx.util.StringUtils;


/**
 * <p>
 * Title: PhoneValidator.java</p>
 * <p>
 * Description: </p>
 * 
 * @author ken chen
 * @date 2019年5月10日
 * @version 1.0
 */
public class IdCardValidator implements ConstraintValidator<IDCARD, String> {
    /**
     * @author ken chen
     *         <p>
     *         Title: isValid</p>
     *         <p>
     *         Description: 自定义元注解校验</p>
     */

    @Override
    public boolean isValid(String cardNo, ConstraintValidatorContext context) {
        if (StringUtils.isEmpty(cardNo)) {
            return true;
        }
        
        if(null!=cardNo&&cardNo.trim().length()==15){
            cardNo=cardNo.trim();
            StringBuffer sb=new StringBuffer(cardNo);
            sb.insert(6, "19");
            sb.append(transCardLastNo(sb.toString()));
            cardNo=sb.toString();
        }
        //18位身份证 正则表达
        IsValidldCardInterface isValidld=new IsValidIdCard();
        String result=isValidld.isValidldCard(cardNo);
        if("".equals(result)) {
            return true;
        }
        return false;
    }
    /**
    * @author ken chen
    * <p>Title: transCardLastNo</p>
    * <p>Description: 15 转换 18身份证补位运算 </p>
    */
    private Object transCardLastNo(String newCardId) {
        char[] ch=newCardId.toCharArray();
        int m=0;
        int [] co={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
        char [] verCode=new char[]{'1','0','X','9','8','7','6','5','4','3','2'};
        for (int i = 0; i < newCardId.length(); i++) {
            m+=(ch[i]-'0')*co[i];
        }
        int residue=m%11;
        return String.valueOf(verCode[residue]);
    }
    @Override
    public void initialize(IDCARD constraintAnnotation) {
        
    }

}
View Code

实现类接口

package com.cfam.ruleone;

public interface IsValidldCardInterface {

    /**校验身份证是否正确**/
    String isValidldCard(String idCard);
    
    /**查询身份证性别**/
    String idCardSexCode(String idCard);
    
    /**校验查询身份证所在省份**/
    String province(String idCard);
    
    /**校验查询身份证所在大区**/
    String largeArea(String idCard);
}
View Code

接口实现类

package com.xxx.xxx;

import java.util.HashMap;
import java.util.Map;

public class IsValidIdCard implements IsValidldCardInterface{

    final static int[] xs = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
    final static char[] validate = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' };

    final static Map<Integer, String> region = new HashMap<Integer, String>();
    static {
        region.put(1, "华北局");
        region.put(2, "东北局");
        region.put(3, "华东局");
        region.put(4, "中南局");
        region.put(5, "西南局");
        region.put(6, "西北局");
    }
    // 判断身份证号属于哪个省份
    final static Map<Integer, String> zoneNum = new HashMap<Integer, String>();
    static {
        zoneNum.put(11, "北京市");
        zoneNum.put(12, "天津市");
        zoneNum.put(13, "河北省");
        zoneNum.put(14, "山西省");
        zoneNum.put(15, "内蒙古自治区");
        zoneNum.put(21, "辽宁省");
        zoneNum.put(22, "吉林省");
        zoneNum.put(23, "黑龙江省");
        zoneNum.put(31, "上海市");
        zoneNum.put(32, "江苏省");
        zoneNum.put(33, "浙江省");
        zoneNum.put(34, "安徽省");
        zoneNum.put(35, "福建省");
        zoneNum.put(36, "江西省");
        zoneNum.put(37, "山东省");
        zoneNum.put(41, "河南省");
        zoneNum.put(42, "湖北省");
        zoneNum.put(43, "湖南省");
        zoneNum.put(44, "广东省");
        zoneNum.put(45, "广西壮族自治区");
        zoneNum.put(46, "海南省");
        zoneNum.put(50, "重庆市");
        zoneNum.put(51, "四川省");
        zoneNum.put(52, "贵州省");
        zoneNum.put(53, "云南省");
        zoneNum.put(54, "西藏自治区");
        zoneNum.put(61, "陕西省");
        zoneNum.put(62, "甘肃省");
        zoneNum.put(63, "青海省");
        zoneNum.put(64, "宁夏回族自治区");
        zoneNum.put(65, "新疆维吾尔自治区");
        zoneNum.put(83, "台湾地区");
        zoneNum.put(81, "香港特别行政区");
        zoneNum.put(82, "澳门特别行政区");
        zoneNum.put(91, "非大陆居民");
    }
    /**
     * 校验身份证证号码是否符合规范
     * @author cjy 
     * @param 身份证号
     * @return 返回错误信息 正确返回""
     * **/
    @Override
    public final String isValidldCard(String idcard) {
        String result=isValidToldCard(idcard);
        return result;
    }
    
    public final static String isValidToldCard(String idcard) {
        //校验身份证号位数是否18位
        String result="";
        result=check(idcard);
        //校验身份证号算法计算后是否正确
        result = isValidld(idcard);
        return result;
    }
    
    
    
    /**
     * 计算方法计算身份证是否符合规范
     * @author cjy
     * @param idcard 身份证号
     * @return 正确返回 "" 错误返回错误信息
     * **/
    private static String isValidld(String idcard) {
        //判断身份证是否符合身份证算法
        boolean result=idcardValidld(idcard);
        //判断身份证年月日是否正确
        boolean residcard=idcardYearAndMonthAndDay(idcard);
        if(result||residcard) {
            return "身份证不合法,请重新输入!";
        }else {
            return"";
        }
    }

    /**
     * 判断身份证是否是18位数
     * @param idcard 身份证号
     * @author cjy
     * @return 正确返回 "" 错误返回错误信息
     * **/ 
    private static final String check(String idcard) {
        if (idcard.length() != 18) {
            return "身份证号位数不正确";
        }
        return "";
    }

    /**
     * 判断身份证属于那一个大区
     * @author cjy
     * @param idcard 身份证号
     * @return 查询到返回查询信息 未查询到返回 ""
     * **/ 
    @Override
    public final String largeArea(String idCard) {
        String result="";
        result=isValidldCard(idCard);
        if("".equals(result)) {
        String provincenew = idCard.substring(0, 1);
            if (region.containsKey(Integer.parseInt(provincenew))) {
                return region.get(Integer.parseInt(provincenew));
            }
        }
        return "";
    }

    /**
     * 判断身份证当前身份省份
     * @author cjy
     * @param idcard 身份证号
     * @return 查询到返回查询身份 未查询到返回 ""
     * **/ 
    @Override
    public final String province(String idCard) {
        String result="";
        result=isValidldCard(idCard);
        if("".equals(result)) {
            String province = idCard.substring(0, 2);
            if (zoneNum.containsKey(Integer.parseInt(province))) {
                return zoneNum.get(Integer.parseInt(province));
            }
            return "";
        }
        return result;
    }

    /**
     * 获取身份证是否正确校验码是否正确
     * @author cjy
     * @param idcard 18位身份证号 
     * @param idcard17 第十八位身份
     * **/
    private static final boolean idCardLast(String idcard18, String idcard) {
        String subidcard18 = idcard.toUpperCase().toString().substring(17, 18);
        if (!idcard18.equals(subidcard18)) {
            return true;
        }
        return false;
    }

    /**
     * 对身份证进行取模运算
     * @author cjy
     * @param idcard 身份证号 
     * @return 验证正确返回false 验证错误返回 true
     * **/ 
    private static final boolean idcardValidld(String idcard) {
        final char[] newIdcard = idcard.toUpperCase().toCharArray();
        // 总值
        int sum = 0;
        // 取模后的值
        int mod = 0;
        // 前17位累加
        for (int i = 0; i < 17; i++) {
            sum += Integer.parseInt(String.valueOf(newIdcard[i])) * xs[i];
        }
        mod = sum % 11;
        // 经过计算得出校验码
        char mods = validate[mod];
        String idcard17 = String.valueOf(mods);
        boolean result = idCardLast(idcard17, idcard);
        if (result) {
            return true;
        }
        return false;
    }
    /**
     * 获取当前身份证性别
     * @author cjy
     * @param idCard 身份证号
     * @return 返回性别
     * **/
    @Override
    public final String idCardSexCode(String idCard) {
        String result="";
        result=isValidldCard(idCard);
        if("".equals(result)) {
            int sexCode = Integer.parseInt(idCard.substring(14, 17));
            if (sexCode % 2 != 0) {
                result="男";
                return result;
            } else {
                result="女";
                return result;
            }
        }
        return result;
    }
    /**
     * 判断时间YYYYMMDD格式是否正确
     * @author cjy
     * @param idcard 身份证号
     * @return 验证正确返回false 返回错误返回true
     * **/
    private static final boolean idcardYearAndMonthAndDay(String idcard) {
        String yearMonthDay = idcard.substring(7, 14);
        boolean result = isValid(yearMonthDay);
        return result;
    }
    /**
     * 
     * 判断时间YYYYMMDD格式是否正确
     * @author cjy
     * @param date_yyyyMMdd
     * @return 校验正确返回 false 校验错误返回true
     * **/
    private static final boolean isValid(String date_yyyyMMdd) {
        try {
            if (date_yyyyMMdd != null && !date_yyyyMMdd.equals("")) {
                if (date_yyyyMMdd.length() == 8) {
                    // 闰年标志
                    boolean isLeapYear = false;
                    String year = date_yyyyMMdd.substring(0, 4);
                    String month = date_yyyyMMdd.substring(4, 6);
                    String day = date_yyyyMMdd.substring(6, 8);
                    int vYear = Integer.parseInt(year);
                    // 判断年份是否合法
                    if (vYear < 1900 || vYear > 2200) {
                        return false;
                    }
                    // 判断是否为闰年
                    if (vYear % 4 == 0 && vYear % 100 != 0 || vYear % 400 == 0) {
                        isLeapYear = true;
                    }
                    // 判断月份
                    if (month.startsWith("0")) {
                        String units4Month = month.substring(1, 2);
                        int vUnits4Month = Integer.parseInt(units4Month);
                        if (vUnits4Month == 0) {
                            return false;
                        }
                        if (vUnits4Month == 2) {
                            // 获取2月的天数
                            int vDays4February = Integer.parseInt(day);
                            if (isLeapYear) {
                                if (vDays4February > 29)
                                    return false;
                            } else {
                                if (vDays4February > 28)
                                    return false;
                            }
                        }
                    } else {
                        // 2.判断非0打头的月份是否合法
                        int vMonth = Integer.parseInt(month);
                        if (vMonth != 10 && vMonth != 11 && vMonth != 12) {
                            return false;
                        }
                    }
                    // 1.判断日期
                    if (day.startsWith("0")) {
                        String units4Day = day.substring(1, 2);
                        int vUnits4Day = Integer.parseInt(units4Day);
                        if (vUnits4Day == 0) {
                            return false;
                        }
                    } else {
                        // 2.判断非0打头的日期是否合法
                        int vDay = Integer.parseInt(day);
                        if (vDay < 10 || vDay > 31) {
                            return false;
                        }
                    }
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
    }
}
View Code

 测试入口

public class IsValidYYYYMMDD {

    public static void main(String[] args) {
        
        IsValidldCardInterface t=new IsValidIdCard();
        System.out.println(t.idCardSexCode("220183199609036417"));
    }


}

 

posted @ 2019-11-08 16:23  我是小金人  阅读(694)  评论(0)    收藏  举报