身份证校验,非正则校验,身份证算法校验。(标签校验 或者方法校验)
身份证校验标签校验
使用需要 @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; }
身份证校验入口
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 {}; }
身份证实现类
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) { } }
实现类接口
package com.cfam.ruleone; public interface IsValidldCardInterface { /**校验身份证是否正确**/ String isValidldCard(String idCard); /**查询身份证性别**/ String idCardSexCode(String idCard); /**校验查询身份证所在省份**/ String province(String idCard); /**校验查询身份证所在大区**/ String largeArea(String idCard); }
接口实现类
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; } } }
测试入口
public class IsValidYYYYMMDD { public static void main(String[] args) { IsValidldCardInterface t=new IsValidIdCard(); System.out.println(t.idCardSexCode("220183199609036417")); } }