mirror of
https://gitee.com/dromara/hutool.git
synced 2025-07-17 01:46:22 +08:00
add CreditCodeUtil
This commit is contained in:
parent
ec0f837037
commit
249f20d0ed
@ -14,6 +14,7 @@
|
|||||||
* 【db 】 设置全局忽略大小写DbUtil.setCaseInsensitiveGlobal(true)(issue#784@Github)
|
* 【db 】 设置全局忽略大小写DbUtil.setCaseInsensitiveGlobal(true)(issue#784@Github)
|
||||||
* 【core 】 增加CallerUtil.getCallerMethodName方法
|
* 【core 】 增加CallerUtil.getCallerMethodName方法
|
||||||
* 【core 】 Tree增加getParent方法,可以获取父节点,抽象Node接口
|
* 【core 】 Tree增加getParent方法,可以获取父节点,抽象Node接口
|
||||||
|
* 【core 】 增加社会信用代码工具CreditCodeUtil(pr#112@Gitee)
|
||||||
|
|
||||||
### Bug修复
|
### Bug修复
|
||||||
* 【core 】 修复TypeUtil无法获取泛型接口的泛型参数问题(issue#I1BRFI@Gitee)
|
* 【core 】 修复TypeUtil无法获取泛型接口的泛型参数问题(issue#I1BRFI@Gitee)
|
||||||
|
@ -1,65 +1,108 @@
|
|||||||
package cn.hutool.core.lang;
|
package cn.hutool.core.lang;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.ReUtil;
|
import cn.hutool.core.util.ReUtil;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 常用正则表达式集合
|
* 常用正则表达式集合
|
||||||
*
|
*
|
||||||
* @author Looly
|
* @author Looly
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class PatternPool {
|
public class PatternPool {
|
||||||
|
|
||||||
/** 英文字母 、数字和下划线 */
|
/**
|
||||||
|
* 英文字母 、数字和下划线
|
||||||
|
*/
|
||||||
public final static Pattern GENERAL = Pattern.compile("^\\w+$");
|
public final static Pattern GENERAL = Pattern.compile("^\\w+$");
|
||||||
/** 数字 */
|
/**
|
||||||
|
* 数字
|
||||||
|
*/
|
||||||
public final static Pattern NUMBERS = Pattern.compile("\\d+");
|
public final static Pattern NUMBERS = Pattern.compile("\\d+");
|
||||||
/** 字母 */
|
/**
|
||||||
|
* 字母
|
||||||
|
*/
|
||||||
public final static Pattern WORD = Pattern.compile("[a-zA-Z]+");
|
public final static Pattern WORD = Pattern.compile("[a-zA-Z]+");
|
||||||
/** 单个中文汉字 */
|
/**
|
||||||
|
* 单个中文汉字
|
||||||
|
*/
|
||||||
public final static Pattern CHINESE = Pattern.compile(ReUtil.RE_CHINESE);
|
public final static Pattern CHINESE = Pattern.compile(ReUtil.RE_CHINESE);
|
||||||
/** 中文汉字 */
|
/**
|
||||||
|
* 中文汉字
|
||||||
|
*/
|
||||||
public final static Pattern CHINESES = Pattern.compile(ReUtil.RE_CHINESES);
|
public final static Pattern CHINESES = Pattern.compile(ReUtil.RE_CHINESES);
|
||||||
/** 分组 */
|
/**
|
||||||
|
* 分组
|
||||||
|
*/
|
||||||
public final static Pattern GROUP_VAR = Pattern.compile("\\$(\\d+)");
|
public final static Pattern GROUP_VAR = Pattern.compile("\\$(\\d+)");
|
||||||
/** IP v4 */
|
/**
|
||||||
|
* IP v4
|
||||||
|
*/
|
||||||
public final static Pattern IPV4 = Pattern.compile("\\b((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\b");
|
public final static Pattern IPV4 = Pattern.compile("\\b((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\b");
|
||||||
/** IP v6 */
|
/**
|
||||||
|
* IP v6
|
||||||
|
*/
|
||||||
public final static Pattern IPV6 = Pattern.compile("(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]+|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9]))");
|
public final static Pattern IPV6 = Pattern.compile("(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]+|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9]))");
|
||||||
/** 货币 */
|
/**
|
||||||
|
* 货币
|
||||||
|
*/
|
||||||
public final static Pattern MONEY = Pattern.compile("^(\\d+(?:\\.\\d+)?)$");
|
public final static Pattern MONEY = Pattern.compile("^(\\d+(?:\\.\\d+)?)$");
|
||||||
/** 邮件,符合RFC 5322规范,正则来自:http://emailregex.com/ */
|
/**
|
||||||
|
* 邮件,符合RFC 5322规范,正则来自:http://emailregex.com/
|
||||||
|
*/
|
||||||
// public final static Pattern EMAIL = Pattern.compile("(\\w|.)+@\\w+(\\.\\w+){1,2}");
|
// public final static Pattern EMAIL = Pattern.compile("(\\w|.)+@\\w+(\\.\\w+){1,2}");
|
||||||
public final static Pattern EMAIL = Pattern.compile("(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)])", Pattern.CASE_INSENSITIVE);
|
public final static Pattern EMAIL = Pattern.compile("(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)])", Pattern.CASE_INSENSITIVE);
|
||||||
/** 移动电话 */
|
/**
|
||||||
|
* 移动电话
|
||||||
|
*/
|
||||||
public final static Pattern MOBILE = Pattern.compile("(?:0|86|\\+86)?1[3456789]\\d{9}");
|
public final static Pattern MOBILE = Pattern.compile("(?:0|86|\\+86)?1[3456789]\\d{9}");
|
||||||
/** 18位身份证号码 */
|
/**
|
||||||
|
* 18位身份证号码
|
||||||
|
*/
|
||||||
public final static Pattern CITIZEN_ID = Pattern.compile("[1-9]\\d{5}[1-2]\\d{3}((0\\d)|(1[0-2]))(([012]\\d)|3[0-1])\\d{3}(\\d|X|x)");
|
public final static Pattern CITIZEN_ID = Pattern.compile("[1-9]\\d{5}[1-2]\\d{3}((0\\d)|(1[0-2]))(([012]\\d)|3[0-1])\\d{3}(\\d|X|x)");
|
||||||
/** 邮编 */
|
/**
|
||||||
|
* 邮编
|
||||||
|
*/
|
||||||
public final static Pattern ZIP_CODE = Pattern.compile("[1-9]\\d{5}(?!\\d)");
|
public final static Pattern ZIP_CODE = Pattern.compile("[1-9]\\d{5}(?!\\d)");
|
||||||
/** 生日 */
|
/**
|
||||||
|
* 生日
|
||||||
|
*/
|
||||||
public final static Pattern BIRTHDAY = Pattern.compile("^(\\d{2,4})([/\\-.年]?)(\\d{1,2})([/\\-.月]?)(\\d{1,2})日?$");
|
public final static Pattern BIRTHDAY = Pattern.compile("^(\\d{2,4})([/\\-.年]?)(\\d{1,2})([/\\-.月]?)(\\d{1,2})日?$");
|
||||||
/** URL */
|
/**
|
||||||
|
* URL
|
||||||
|
*/
|
||||||
public final static Pattern URL = Pattern.compile("[a-zA-z]+://[^\\s]*");
|
public final static Pattern URL = Pattern.compile("[a-zA-z]+://[^\\s]*");
|
||||||
/** Http URL */
|
/**
|
||||||
|
* Http URL
|
||||||
|
*/
|
||||||
public final static Pattern URL_HTTP = Pattern.compile("(https://|http://)?([\\w-]+\\.)+[\\w-]+(:\\d+)*(/[\\w- ./?%&=]*)?");
|
public final static Pattern URL_HTTP = Pattern.compile("(https://|http://)?([\\w-]+\\.)+[\\w-]+(:\\d+)*(/[\\w- ./?%&=]*)?");
|
||||||
/** 中文字、英文字母、数字和下划线 */
|
/**
|
||||||
|
* 中文字、英文字母、数字和下划线
|
||||||
|
*/
|
||||||
public final static Pattern GENERAL_WITH_CHINESE = Pattern.compile("^[\u4E00-\u9FFF\\w]+$");
|
public final static Pattern GENERAL_WITH_CHINESE = Pattern.compile("^[\u4E00-\u9FFF\\w]+$");
|
||||||
/** UUID */
|
/**
|
||||||
|
* UUID
|
||||||
|
*/
|
||||||
public final static Pattern UUID = Pattern.compile("^[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}$");
|
public final static Pattern UUID = Pattern.compile("^[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}$");
|
||||||
/** 不带横线的UUID */
|
/**
|
||||||
|
* 不带横线的UUID
|
||||||
|
*/
|
||||||
public final static Pattern UUID_SIMPLE = Pattern.compile("^[0-9a-z]{32}$");
|
public final static Pattern UUID_SIMPLE = Pattern.compile("^[0-9a-z]{32}$");
|
||||||
/** MAC地址正则 */
|
/**
|
||||||
|
* MAC地址正则
|
||||||
|
*/
|
||||||
public static final Pattern MAC_ADDRESS = Pattern.compile("((?:[A-F0-9]{1,2}[:-]){5}[A-F0-9]{1,2})|(?:0x)(\\d{12})(?:.+ETHER)", Pattern.CASE_INSENSITIVE);
|
public static final Pattern MAC_ADDRESS = Pattern.compile("((?:[A-F0-9]{1,2}[:-]){5}[A-F0-9]{1,2})|(?:0x)(\\d{12})(?:.+ETHER)", Pattern.CASE_INSENSITIVE);
|
||||||
/** 16进制字符串 */
|
/**
|
||||||
|
* 16进制字符串
|
||||||
|
*/
|
||||||
public static final Pattern HEX = Pattern.compile("^[a-f0-9]+$", Pattern.CASE_INSENSITIVE);
|
public static final Pattern HEX = Pattern.compile("^[a-f0-9]+$", Pattern.CASE_INSENSITIVE);
|
||||||
/** 时间正则 */
|
/**
|
||||||
|
* 时间正则
|
||||||
|
*/
|
||||||
public static final Pattern TIME = Pattern.compile("\\d{1,2}:\\d{1,2}(:\\d{1,2})?");
|
public static final Pattern TIME = Pattern.compile("\\d{1,2}:\\d{1,2}(:\\d{1,2})?");
|
||||||
/** 中国车牌号码(兼容新能源车牌) */
|
/**
|
||||||
|
* 中国车牌号码(兼容新能源车牌)
|
||||||
|
*/
|
||||||
public final static Pattern PLATE_NUMBER = Pattern.compile(
|
public final static Pattern PLATE_NUMBER = Pattern.compile(
|
||||||
//https://gitee.com/loolly/hutool/issues/I1B77H?from=project-issue
|
//https://gitee.com/loolly/hutool/issues/I1B77H?from=project-issue
|
||||||
"^(([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z](([0-9]{5}[ABCDEFGHJK])|([ABCDEFGHJK]([A-HJ-NP-Z0-9])[0-9]{4})))|" +
|
"^(([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z](([0-9]{5}[ABCDEFGHJK])|([ABCDEFGHJK]([A-HJ-NP-Z0-9])[0-9]{4})))|" +
|
||||||
@ -68,14 +111,22 @@ public class PatternPool {
|
|||||||
"([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳使领]))$");
|
"([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳使领]))$");
|
||||||
|
|
||||||
|
|
||||||
/** 社会统一信用代码 */
|
/**
|
||||||
public static final String CREDIT_CODE = "^[A-Z0-9]{18}$";
|
* 社会统一信用代码
|
||||||
|
* <pre>
|
||||||
public static final String BASE_CODE_REGEX = "[0-9A-Y]{18}";
|
* 第一部分:登记管理部门代码1位 (数字或大写英文字母)
|
||||||
|
* 第二部分:机构类别代码1位 (数字或大写英文字母)
|
||||||
|
* 第三部分:登记管理机关行政区划码6位 (数字)
|
||||||
|
* 第四部分:主体标识码(组织机构代码)9位 (数字或大写英文字母)
|
||||||
|
* 第五部分:校验码1位 (数字或大写英文字母)
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public static final Pattern CREDIT_CODE = Pattern.compile("^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$");
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
/** Pattern池 */
|
/**
|
||||||
|
* Pattern池
|
||||||
|
*/
|
||||||
private static final SimpleCache<RegexWithFlag, Pattern> POOL = new SimpleCache<>();
|
private static final SimpleCache<RegexWithFlag, Pattern> POOL = new SimpleCache<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,11 +176,11 @@ public class PatternPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 正则表达式和正则标识位的包装
|
* 正则表达式和正则标识位的包装
|
||||||
*
|
*
|
||||||
* @author Looly
|
* @author Looly
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
private static class RegexWithFlag {
|
private static class RegexWithFlag {
|
||||||
private String regex;
|
private String regex;
|
||||||
|
@ -2,14 +2,13 @@ package cn.hutool.core.lang;
|
|||||||
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.exceptions.ValidateException;
|
import cn.hutool.core.exceptions.ValidateException;
|
||||||
|
import cn.hutool.core.util.CreditCodeUtil;
|
||||||
import cn.hutool.core.util.NumberUtil;
|
import cn.hutool.core.util.NumberUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.ReUtil;
|
import cn.hutool.core.util.ReUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@ -89,17 +88,6 @@ public class Validator {
|
|||||||
*/
|
*/
|
||||||
public final static Pattern PLATE_NUMBER = PatternPool.PLATE_NUMBER;
|
public final static Pattern PLATE_NUMBER = PatternPool.PLATE_NUMBER;
|
||||||
|
|
||||||
/**
|
|
||||||
* 社会统一信用代码
|
|
||||||
*/
|
|
||||||
public static final List<Character> BASE_CODES = new ArrayList<>();
|
|
||||||
|
|
||||||
public static final String BASE_CODE_STRING = "0123456789ABCDEFGHJKLMNPQRTUWXY";
|
|
||||||
|
|
||||||
public static final int[] WEIGHT = {1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28};
|
|
||||||
|
|
||||||
public static final char[] BASE_CODE_ARRAY = BASE_CODE_STRING.toCharArray();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 给定值是否为<code>true</code>
|
* 给定值是否为<code>true</code>
|
||||||
*
|
*
|
||||||
@ -136,7 +124,7 @@ public class Validator {
|
|||||||
if (isFalse(value)) {
|
if (isFalse(value)) {
|
||||||
throw new ValidateException(errorMsgTemplate, params);
|
throw new ValidateException(errorMsgTemplate, params);
|
||||||
}
|
}
|
||||||
return value;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -153,7 +141,7 @@ public class Validator {
|
|||||||
if (isTrue(value)) {
|
if (isTrue(value)) {
|
||||||
throw new ValidateException(errorMsgTemplate, params);
|
throw new ValidateException(errorMsgTemplate, params);
|
||||||
}
|
}
|
||||||
return value;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -191,7 +179,7 @@ public class Validator {
|
|||||||
if (isNotNull(value)) {
|
if (isNotNull(value)) {
|
||||||
throw new ValidateException(errorMsgTemplate, params);
|
throw new ValidateException(errorMsgTemplate, params);
|
||||||
}
|
}
|
||||||
return value;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1117,38 +1105,21 @@ public class Validator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 简单校验统一社会信用代码
|
|
||||||
* 18位(大写字母+数字)
|
|
||||||
*
|
|
||||||
* @param creditCode 统一社会信用代码
|
|
||||||
* @return 校验结果
|
|
||||||
*/
|
|
||||||
public static boolean isCreditCodeBySimple(String creditCode) {
|
|
||||||
if (StrUtil.isBlank(creditCode)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Pattern.matches(PatternPool.CREDIT_CODE, creditCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否是有效的统一社会信用代码
|
* 是否是有效的统一社会信用代码
|
||||||
|
* <pre>
|
||||||
|
* 第一部分:登记管理部门代码1位 (数字或大写英文字母)
|
||||||
|
* 第二部分:机构类别代码1位 (数字或大写英文字母)
|
||||||
|
* 第三部分:登记管理机关行政区划码6位 (数字)
|
||||||
|
* 第四部分:主体标识码(组织机构代码)9位 (数字或大写英文字母)
|
||||||
|
* 第五部分:校验码1位 (数字或大写英文字母)
|
||||||
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param creditCode 统一社会信用代码
|
* @param creditCode 统一社会信用代码
|
||||||
* @return 校验结果
|
* @return 校验结果
|
||||||
|
* @since 5.2.4
|
||||||
*/
|
*/
|
||||||
public static boolean isCreditCode(String creditCode) {
|
public static boolean isCreditCode(CharSequence creditCode) {
|
||||||
if (StrUtil.isBlank(creditCode) || !Pattern.matches(PatternPool.BASE_CODE_REGEX, creditCode)) {
|
return CreditCodeUtil.isCreditCode(creditCode);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
char[] businessCodeArray = creditCode.toCharArray();
|
|
||||||
char check = businessCodeArray[17];
|
|
||||||
int sum = 0, length = 17;
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
char key = businessCodeArray[i];
|
|
||||||
sum += (BASE_CODES.indexOf(key) * WEIGHT[i]);
|
|
||||||
}
|
|
||||||
int value = 31 - sum % 31;
|
|
||||||
return check == BASE_CODE_ARRAY[value % 31];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,131 @@
|
|||||||
|
package cn.hutool.core.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.PatternPool;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一社会信用代码工具类
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* 第一部分:登记管理部门代码1位 (数字或大写英文字母)
|
||||||
|
* 第二部分:机构类别代码1位 (数字或大写英文字母)
|
||||||
|
* 第三部分:登记管理机关行政区划码6位 (数字)
|
||||||
|
* 第四部分:主体标识码(组织机构代码)9位 (数字或大写英文字母)
|
||||||
|
* 第五部分:校验码1位 (数字或大写英文字母)
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author looly
|
||||||
|
* @since 5.2.4
|
||||||
|
*/
|
||||||
|
public class CreditCodeUtil {
|
||||||
|
|
||||||
|
public static final Pattern CREDIT_CODE_PATTERN = PatternPool.CREDIT_CODE;
|
||||||
|
|
||||||
|
private static final int[] WEIGHT = {1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28};
|
||||||
|
private static final char[] BASE_CODE_ARRAY = "0123456789ABCDEFGHJKLMNPQRTUWXY".toCharArray();
|
||||||
|
private static final Map<Character, Integer> CODE_INDEX_MAP;
|
||||||
|
|
||||||
|
static {
|
||||||
|
CODE_INDEX_MAP = new ConcurrentHashMap<>();
|
||||||
|
for (int i = 0; i < BASE_CODE_ARRAY.length; i++) {
|
||||||
|
CODE_INDEX_MAP.put(BASE_CODE_ARRAY[i], i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 正则校验统一社会信用代码(18位)
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* 第一部分:登记管理部门代码1位 (数字或大写英文字母)
|
||||||
|
* 第二部分:机构类别代码1位 (数字或大写英文字母)
|
||||||
|
* 第三部分:登记管理机关行政区划码6位 (数字)
|
||||||
|
* 第四部分:主体标识码(组织机构代码)9位 (数字或大写英文字母)
|
||||||
|
* 第五部分:校验码1位 (数字或大写英文字母)
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param creditCode 统一社会信用代码
|
||||||
|
* @return 校验结果
|
||||||
|
*/
|
||||||
|
public static boolean isCreditCodeSimple(CharSequence creditCode) {
|
||||||
|
if (StrUtil.isBlank(creditCode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ReUtil.isMatch(CREDIT_CODE_PATTERN, creditCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是有效的统一社会信用代码
|
||||||
|
* <pre>
|
||||||
|
* 第一部分:登记管理部门代码1位 (数字或大写英文字母)
|
||||||
|
* 第二部分:机构类别代码1位 (数字或大写英文字母)
|
||||||
|
* 第三部分:登记管理机关行政区划码6位 (数字)
|
||||||
|
* 第四部分:主体标识码(组织机构代码)9位 (数字或大写英文字母)
|
||||||
|
* 第五部分:校验码1位 (数字或大写英文字母)
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param creditCode 统一社会信用代码
|
||||||
|
* @return 校验结果
|
||||||
|
*/
|
||||||
|
public static boolean isCreditCode(CharSequence creditCode) {
|
||||||
|
if (false == isCreditCodeSimple(creditCode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int parityBit = getParityBit(creditCode);
|
||||||
|
if (parityBit < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return creditCode.charAt(17) == BASE_CODE_ARRAY[parityBit];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取一个随机的统一社会信用代码
|
||||||
|
*
|
||||||
|
* @return 统一社会信用代码
|
||||||
|
*/
|
||||||
|
public static String randomCreditCode() {
|
||||||
|
final StringBuilder buf = new StringBuilder(18);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
int num = RandomUtil.randomInt(BASE_CODE_ARRAY.length - 1);
|
||||||
|
buf.append(Character.toUpperCase(BASE_CODE_ARRAY[num]));
|
||||||
|
}
|
||||||
|
for (int i = 2; i < 8; i++) {
|
||||||
|
int num = RandomUtil.randomInt(10);
|
||||||
|
buf.append(Character.toUpperCase(BASE_CODE_ARRAY[num]));
|
||||||
|
}
|
||||||
|
for (int i = 8; i < 17; i++) {
|
||||||
|
int num = RandomUtil.randomInt(BASE_CODE_ARRAY.length - 1);
|
||||||
|
buf.append(Character.toUpperCase(BASE_CODE_ARRAY[num]));
|
||||||
|
}
|
||||||
|
|
||||||
|
final String code = buf.toString();
|
||||||
|
return code + BASE_CODE_ARRAY[getParityBit(code)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取校验码
|
||||||
|
*
|
||||||
|
* @param creditCode 统一社会信息代码
|
||||||
|
* @return 获取较验位的值
|
||||||
|
*/
|
||||||
|
private static int getParityBit(CharSequence creditCode) {
|
||||||
|
int sum = 0;
|
||||||
|
Integer codeIndex;
|
||||||
|
for (int i = 0; i < 17; i++) {
|
||||||
|
codeIndex = CODE_INDEX_MAP.get(creditCode.charAt(i));
|
||||||
|
if (null == codeIndex) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
sum += codeIndex * WEIGHT[i];
|
||||||
|
}
|
||||||
|
final int result = 31 - sum % 31;
|
||||||
|
return result == 31 ? 0 : result;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package cn.hutool.core.util;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class CreditCodeUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isCreditCodeBySimple() {
|
||||||
|
String testCreditCode = "91310115591693856A";
|
||||||
|
Assert.assertTrue(CreditCodeUtil.isCreditCodeSimple(testCreditCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isCreditCode() {
|
||||||
|
String testCreditCode = "91310110666007217T";
|
||||||
|
Assert.assertTrue(CreditCodeUtil.isCreditCode(testCreditCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void randomCreditCode() {
|
||||||
|
final String s = CreditCodeUtil.randomCreditCode();
|
||||||
|
Assert.assertTrue(CreditCodeUtil.isCreditCode(s));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user