前面针对数据安全-数据分类分级方案设计做了分析讲解,以及针对日期类型的数据识别做了讲解(数据分类分级 数据识别-识别日期类型数据),也是正则表达式方式,这里不做赘述
敏感数据识别
通过内置数据识别规则或用户数据识别规则,对其结构化表进行整体扫描,自动识别敏感数据,进行分级
敏感字段
统一社会信用代码,车辆识别代码,营业执照号码,税务登记证号码,组织机构代码,图片,日期,IP地址,MAC地址,城市,性别,民族,省份,车牌号,电话号码,军官证,邮箱,护照号,港澳通行证,姓名,地址,手机号,身份证,银行卡
敏感字段识别方式
识别方式:正则匹配,关键字,算法
- 银行卡号、证件号、手机号等,有明确的规则,可以根据正则表达式和算法匹配
- 姓名、特殊字段等,没有明确信息,可能是任意字符串,可以通过配置关键字来进行匹配
- 营业执照、地址、图片等,没有明确规则,可以通过自然语言算法来识别,使用开源算法库
敏感数据识别规则 代码示例
正则表达式
正则表达式校验工具类
//正则表达式工具,用于校验是否为合法的正则表达式和各种正则校验
public class RegexUtil {
public static boolean checkRegex(String regexStr) {
try {
Pattern.compile(regexStr); // 尝试编译正则表达式
return true;
} catch (PatternSyntaxException e) {
return false;
}
}
}
身份证号
// 验证身份证号
public static boolean checkIdNumber(String idNumber) {
try {
Pattern p = Pattern
.compile("^[1-9]\\d{5}(19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$");
//根据国家标准 GB 11643-1999 的规定,公民身份号码是由十七位数字本体码和一位数字校验码组成,排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
//开始和结束都是 ^ 和 $ ,表示从开头到结束,没有其他字符。
//[1-9]\d{5}:匹配前六位数字地址码,第一位数字不能为0。
//(19|20)\d{2}:匹配出生年份,限定为19xx或20xx。
//((0[1-9])|(1[0-2])):匹配出生月份,取值范围为01-12。
//(([0-2][1-9])|10|20|30|31):匹配出生日期,取值范围为01-31。
//\d{3}:匹配三位数字顺序码。
//[0-9Xx]:匹配一位数字校验码,其中 X/x 可以作为校验码的占位符。
//需要注意的是,以上正则表达式虽然可以大致判断出身份证号是否符合规范,但并不能保证校验码的正确性,因为得到校验码需要使用一定的算法进行计算,并不是简单的通过正则表达式匹配即可得到。
Matcher m = p.matcher(idNumber);
System.out.println("idNumber:" + m.matches());
return m.matches();
} catch (Exception e) {
return false;
}
}
手机号
// 验证手机号
public static boolean checkTel(String tel) {
try {
Pattern p = Pattern
.compile("^1[3-9]\\d{9}$");
//中国手机号码的号段是固定的,根据国家和工信部的规定,目前中国大陆手机号段如下:
//移动:134、135、136、137、138、139、147、148、150、151、152、157、158、159、165、172、178、182、183、184、187、188、195、197、198。
//联通:130、131、132、145、146、155、156、166、171、175、176、185、186、196。
//电信:133、149、153、173、177、180、181、189、191、199。
Matcher m = p.matcher(tel);
System.out.println("checkTel:" +m.matches());
return m.matches();
} catch (Exception e) {
return false;
}
}
座机号
//识别座机号码
public static boolean checkFixedPhone(String fixedPhone) {
try {
Pattern p = Pattern
.compile("^0\\d{2,3}-\\d{7,8}$|^0\\d{10}$|^\\d{7,8}$");
//国座机号码由区号和电话号码组成,通常为 3 位或 4 位区号加上 7 位电话号码,总长度为 11 位。
//该正则表达式匹配包含连字符和不包含连字符两种格式的座机号码,其中:
//^0\d{2}-\d{7,8}$ 匹配 3 位座机区号 + 7~8 位座机号码(有连字符)的格式。
//^0\d{3}-\d{7,8}$ 匹配 4 位座机区号 + 7~8 位座机号码(有连字符)的格式。
//^0\d{10}$ 匹配 11 位座机号码(无连字符)的格式。
//^\d{7,8}$ 匹配无座机区号,只有座机号码的格式
Matcher m = p.matcher(fixedPhone);
System.out.println("checkFixedPhone:" +m.matches());
return m.matches();
} catch (Exception e) {
return false;
}
}
邮箱地址
直接使用正则验证
public static boolean checkEmail(String email) {
try {
//\w+@(\w+.)+[a-z]{2,3}
//[\w-]+@[\w-]+(.[\w-]+)+
Pattern p = Pattern
.compile("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");
//该正则表达式匹配符合常规邮件格式的字符串,其中:
//
//开始和结束都是 ^ 和 $ ,表示从开头到结束,没有其他字符。
//[a-zA-Z0-9._%+-]+:以字母数字或者点、下划线、百分号、减号以及加号开头,可以出现一次或多次。
//@:紧跟着上述字符之后,一个 @ 符号。
//[a-zA-Z0-9.-]+:@ 符号之后,可以出现一个或多个字母数字或减号或点。
//\.:表示必须有一个小数点(.),且该小数点需要转义。
//[a-zA-Z]{2,}:小数点之后,必须有两个或以上的字母,不能有其他字符。
//这个正则表达式可以匹配类似 "example@domain.com" 格式的常见邮箱地址。请注意:该正则表达式只是简单的识别常见邮箱的格式,不保证该邮箱地址是有效的或确实存在。
Matcher m = p.matcher(email);
System.out.println("checkEmail:" + m.matches());
return m.matches();
} catch (Exception e) {
return false;
}
}
使用Apache Commons Validator库中的方法,用于验证邮箱地址是否有效,该方法的原理也是使用正则表达式来匹配
import org.apache.commons.validator.routines.EmailValidator;
public static boolean isEmail(String email) {
// 验证邮箱地址
EmailValidator emailValidator = EmailValidator.getInstance();
if (emailValidator.isValid(email)) {
System.out.println("Valid email address!");
} else {
System.out.println("Invalid email address!");
}
return emailValidator.isValid(email);
}
Ipv4地址
public static boolean checkIpv4(String Ipv4) {
try {
//^(?:(?: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]?)$
//^(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})$
Pattern p = Pattern
.compile("^((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})$");
//IP地址由四个数字组成,每个数字的范围是 0 到 255,因此需要使用 (?:25[0-5]|2[0-4]\d|[01]?\d{1,2}) 子表达式来匹配每个数字。其中的含义如下:
//(?:) 表示非捕获型分组;
//25[0-5] 匹配 250 到 255 的数字;
//2[0-4]\d 匹配 200 到 249 的数字;
//[01]?\d{1,2} 匹配 0 到 199 的数字,包括前导零。
//. 表示匹配任意字符,因此需要转义为 \. 进行匹配。{3} 表示前面的元素重复 3 次。
//需要注意的是,该正则表达式仅适用于 IPv4 地址
Matcher m = p.matcher(Ipv4);
System.out.println("checkIpv4:" + m.matches());
return m.matches();
} catch (Exception e) {
return false;
}
}
Ipv6地址
public static boolean checkIpv6(String ipv6) {
try {
//^((([0-9a-fA-F]){1,4}):){7}(([0-9a-fA-F]){1,4})$
Pattern p = Pattern
.compile("^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$");
Matcher m = p.matcher(ipv6);
System.out.println("checkIpv6:" + m.matches());
return m.matches();
} catch (Exception e) {
return false;
}
}
MAC地址
public static boolean checkMac(String mac) {
//检查mac地址
try {
Pattern p = Pattern
.compile("^(?:(?:(?:[a-f0-9A-F]{2}:){5})|(?:(?:[a-f0-9A-F]{2}-){5}))[a-f0-9A-F]{2}$");
Matcher m = p.matcher(mac);
System.out.println("checkMac:" + m.matches());
return m.matches();
} catch (Exception e) {
return false;
}
}
中国新旧版、英、美、日、韩、加拿大护照
//验证护照
public static boolean checkPassport(String passport) {
try {
if (Pattern.compile("^([a-zA-z]|[0-9]){5,17}$").matcher(passport).matches()) {
System.out.println("checkPassport: 中国旧版护照");
return true;
} else if (Pattern.compile("^1[45]\\d{7}$").matcher(passport).matches()) {
System.out.println("checkPassport: 中国新版护照");
return true;
} else if (Pattern.compile("^[a-zA-Z0-9]{9}$").matcher(passport).matches()) {
System.out.println("checkPassport: 美国护照");
return true;
} else if (Pattern.compile("^[a-zA-Z0-9]{2}\\d{6}$").matcher(passport).matches()) {
System.out.println("checkPassport: 加拿大护照");
return true;
} else if (Pattern.compile("^[a-zA-Z0-9]{9}$").matcher(passport).matches()) {
System.out.println("checkPassport: 英国护照");
return true;
} else if (Pattern.compile("^P[K|N]\\d{8}$").matcher(passport).matches()) {
System.out.println("checkPassport: 韩国护照");
return true;
} else if (Pattern.compile("^(?!×{2})[D|E|G]\\d{8}$").matcher(passport).matches()) {
System.out.println("checkPassport: 日本护照");
return true;
} else {
System.out.println("checkPassport: 无法识别");
return false;
}
} catch (Exception e) {
return false;
}
}
性别
public static boolean checkGender(String gender) {
try {
Pattern p = Pattern
.compile("^((男|male)|(女|female))$");
Matcher m = p.matcher(gender);
System.out.println("checkGender:" + m.matches());
return m.matches();
} catch (Exception e) {
return false;
}
}
民族
//校验民族
public static boolean checkNational(String national) {
try {
Pattern p = Pattern
.compile("^((汉|满|蒙古|回|藏|维吾尔|苗|彝|壮|布依|侗|瑶|白|土家|哈尼|哈萨克|傣|黎|傈僳|佤|畲|高山|拉祜|水|东乡|纳西|景颇|柯尔克孜|土|达斡尔|仫佬|羌|布朗|撒拉|毛南|仡佬|锡伯|阿昌|普米|朝鲜|塔吉克|怒|乌孜别克|俄罗斯|鄂温克|德昂|保安|裕固|京|塔塔尔|独龙|鄂伦春|赫哲|门巴|珞巴|基诺)|(汉族|满族|蒙古族|回族|藏族|维吾尔族|苗族|彝族|壮族|布依族|侗族|瑶族|白族|土家族|哈尼族|哈萨克族|傣族|黎族|傈僳族|佤族|畲族|高山族|拉祜族|水族|东乡族|纳西族|景颇族|柯尔克孜族|土族|达斡尔族|仫佬族|羌族|布朗族|撒拉族|毛南族|仡佬族|锡伯族|阿昌族|普米族|朝鲜族|塔吉克族|怒族|乌孜别克族|俄罗斯族|鄂温克族|德昂族|保安族|裕固族|京族|塔塔尔族|独龙族|鄂伦春族|赫哲族|门巴族|珞巴族|基诺族))$");
Matcher m = p.matcher(national);
System.out.println("checkNational:" + m.matches());
return m.matches();
} catch (Exception e) {
return false;
}
}
省份
//校验省份
public static boolean checkProvinces(String provinces) {
try {
Pattern p = Pattern
.compile("^(北京市|天津市|上海市|重庆市|河北省|山西省|辽宁省|吉林省|黑龙江省|江苏省|浙江省|安徽省|福建省|江西省|山东省|河南省|湖北省|湖南省|广东省|海南省|四川省|贵州省|云南省|陕西省|甘肃省|青海省|台湾省|内蒙古自治区|广西壮族自治区|西藏自治区|宁夏回族自治区|新疆维吾尔自治区|香港特别行政区|澳门特别行政区)$");
Matcher m = p.matcher(provinces);
System.out.println("checkProvinces:" + m.matches());
return m.matches();
} catch (Exception e) {
return false;
}
}
医师资格证书
//校验医师资格证书
public static boolean checkDoctorQualificationCertificate(String certificate) {
try {
String a = "^[\u4e00-\u9fa5]{2}[\\d]{6}[(\\d)|(X)]{4}[\\dA-Z]{3}[\\d]";
Pattern p = Pattern
.compile("^[\\u4e00-\\u9fa5]{2}\\d{10}$");
Matcher m = p.matcher(certificate);
System.out.println("checkDoctorQualificationCertificate:" + m.matches());
return m.matches();
} catch (Exception e) {
return false;
}
}
医师执业证书
//校验医师执业证书
public static boolean checkDoctorCertificate(String doctorCertificate) {
try {
String a = "^[\u4e00-\u9fa5]{1}[\\w\\d]{14}$";
Pattern p = Pattern
.compile("^[\\u4e00-\\u9fa5]{2}医师执业证\\d{8}号$");
Matcher m = p.matcher(doctorCertificate);
System.out.println("checkDoctorCertificate:" + m.matches());
return m.matches();
} catch (Exception e) {
return false;
}
}
永久居住证
//校验永久居住证
public static boolean checkPRCCard(String idCard) {
try {
Pattern p = Pattern
.compile("^[a-zA-Z0-9]{18}$");
Matcher m = p.matcher(idCard);
System.out.println("checkPRCCard:" + m.matches());
return m.matches();
} catch (Exception e) {
return false;
}
}
港澳通行证
//校验港澳通行证
public static boolean checkHMPass(String HMPass) {
try {
String a = "^[HMhm]{1}([0-9]{10}|[0-9]{8})$";
Pattern p = Pattern
.compile("^HM\\d{8}$|^MA\\d{8}$|^HK\\d{9}$");
Matcher m = p.matcher(HMPass);
System.out.println("checkHMPass:" + m.matches());
return m.matches();
} catch (Exception e) {
return false;
}
}
大陆通行证
public static boolean checkTWPass(String HMPass) {
try {
Pattern p = Pattern
.compile("^[A-Za-z]\\d{9}$");
Matcher m = p.matcher(HMPass);
System.out.println("checkHMPass:" + m.matches());
return m.matches();
} catch (Exception e) {
return false;
}
}
军官证
//校验军官证
public static boolean checkOfficer(String officer) {
try {
Pattern p = Pattern
.compile("^[\\u4E00-\\u9FA5](字第)([0-9a-zA-Z]{4,8})(号?)$");
Matcher m = p.matcher(officer);
System.out.println("checkOfficer:" + m.matches());
return m.matches();
} catch (Exception e) {
return false;
}
}
关键字
地址
这里使用的是开源的中文自然语言处理工具包HanLP,它支持中文分词、词性标注、命名实体识别、关键词提取、自动摘要、情感分析、依存句法分析、文本分类、聚类分析等多种自然语言处理任务。其中,HanLP提供的CRF工具包括了地址解析的功能
校验只能识别,不能确定正确性,如浙江省上海市,照样返回true
引入maven配置
<dependency>
<groupId>com.hankcs</groupId>
<artifactId>hanlp</artifactId>
<version>portable-1.8.8</version>
</dependency>
代码
import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.seg.common.Term;
import java.util.List;
import java.util.regex.Pattern;
public class AddressValidator {
/**
* 判断地址是否合法
*
* @param address 地址
* @return 是否合法
*/
public static boolean isValidAddress(String address) {
// 将地址分词
List<Term> terms = HanLP.segment(address);
// 遍历分词结果,判断是否包含省、市、区/县三个关键词
boolean hasProvince = false;
boolean hasCity = false;
boolean hasDistrict = false;
for (Term term : terms) {
if (term.nature.startsWith("ns") && !hasProvince) {
hasProvince = true;
} else if ((term.nature.startsWith("ns") || term.nature.startsWith("n")) && !hasCity) {
hasCity = true;
} else if ((term.nature.startsWith("ns") || term.nature.startsWith("n")) && !hasDistrict) {
hasDistrict = true;
}
}
// 如果三个关键词都存在,说明地址合法
return hasProvince && hasCity && hasDistrict;
}
/**
* 判断地址是否符合格式要求
*
* @param address 地址
* @return 是否符合格式要求
*/
public static boolean isFormattedAddress(String address) {
// 使用正则表达式判断地址是否符合格式要求
Pattern pattern = Pattern.compile("^\\S+[省市区县]\\S+[市区县]\\S+$");
return pattern.matcher(address).matches();
}
/**
* 判断地址是否合法并且符合格式要求
*
* @param address 地址
* @return 是否合法并且符合格式要求
*/
public static boolean isValidAndFormattedAddress(String address) {
return isValidAddress(address) && isFormattedAddress(address);
}
public static void main(String[] args) {
String address1 = "北京市朝阳区三里屯街道工人体育场北路4号院";
String address2 = "深圳市南山区高新南区清华大学研究生院";
String address3 = "上海市徐汇区钦州北路516号华泾艺校区";
System.out.println(isValidAndFormattedAddress(address1)); // true
System.out.println(isValidAndFormattedAddress(address2)); // true
System.out.println(isValidAndFormattedAddress(address3)); // true
}
}
算法
银行卡
public static boolean checkBankCard(String bankCard) {
if(bankCard.length() < 15 || bankCard.length() > 19) {
return false;
}
char bit = getBankCardCheckCode(bankCard.substring(0, bankCard.length() - 1));
if(bit == 'N'){
return false;
}
boolean checkBankCard = bankCard.charAt(bankCard.length() - 1) == bit;
System.out.println("checkBankCard: " + checkBankCard);
return checkBankCard;
}
/**
* 从不含校验位的银行卡卡号采用 Luhm 校验算法获得校验位
* @param nonCheckCodeBankCard
* @return
*/
public static char getBankCardCheckCode(String nonCheckCodeBankCard){
if(nonCheckCodeBankCard == null || nonCheckCodeBankCard.trim().length() == 0
|| !nonCheckCodeBankCard.matches("\\d+")) {
//如果传的不是数据返回N
return 'N';
}
char[] chs = nonCheckCodeBankCard.trim().toCharArray();
int luhmSum = 0;
for(int i = chs.length - 1, j = 0; i >= 0; i--, j++) {
int k = chs[i] - '0';
if(j % 2 == 0) {
k *= 2;
k = k / 10 + k % 10;
}
luhmSum += k;
}
return (luhmSum % 10 == 0) ? '0' : (char)((10 - luhmSum % 10) + '0');
}
信用卡
CreditCardValidator.genericCreditCardValidator()是Apache Commons Validator 库中的一个方法,用于验证信用卡号是否有效。该方法的原理是根据信用卡号的不同类型(如 Visa、Mastercard、American Express等)确定其对应的校验规则。具体来说,它会通过调用一系列子方法,先根据信用卡号的前几位数字确定信用卡类型,再根据该类型的规则进行校验,最后返回一个布尔值表示是否有效。校验规则通常包括以下几个方面:
- 根据不同类型的信用卡确定长度和开头数字等规则。
- 使用 Luhn 算法对信用卡号进行校验。Luhn 算法是一种简单的校验算法,其原理是将信用卡号每一位上的数字分别乘以 2 或 1,并将乘积的个位数和十位数相加,最后将所有数字相加并求余数,如果余数为 0,则该信用卡号有效。
- 根据特殊规则进行校验,如根据信用卡号的长度和特定数字的组合方式等。
总之,CreditCardValidator.genericCreditCardValidator()
的原理就是根据信用卡号的类型和规则,通过各种校验方式来判断信用卡号是否有效。文章来源:https://www.toymoban.com/news/detail-454288.html
import org.apache.commons.validator.routines.CreditCardValidator;
public static boolean isCreditCard(String creditCard) {
// 验证信用卡号
CreditCardValidator validator = CreditCardValidator.genericCreditCardValidator();
if (validator.isValid(creditCard)) {
System.out.println("Valid credit card number!");
} else {
System.out.println("Invalid credit card number!");
}
return validator.isValid(creditCard);
}
组织机构代码
//校验组织机构代码
public static boolean checkOrgCode(String orgCode) {
//组织机构代码(Organization Code)是由国家工商行政管理总局颁布的统一社会信用代码(Unified Social Credit Code)之前使用的一种企业标识编码体系,编码规则为8位数字或字母加1位校验码。
//该算法主要通过正则表达式验证组织机构代码的格式是否正确,然后使用固定的因子与各个字符进行运算得到一个校验码,并将其与最后一位字符进行比较从而判断组织机构代码是否合法。
if (orgCode == null || orgCode.length() != 9) {
return false;
}
String regex = "[0-9A-Z]{8}[0-9X]";
if (!orgCode.matches(regex)) {
return false;
}
char[] codes = orgCode.toCharArray();
int[] factors = new int[]{3, 7, 9, 10, 5, 8, 4, 2};
char[] checkCodes = "0123456789X".toCharArray();
int sum = 0;
for (int i = 0; i < codes.length - 1; i++) {
char code = codes[i];
int factor = factors[i];
int value = 0;
if (code >= '0' && code <= '9') {
value = code - '0';
} else if (code >= 'A' && code <= 'Z') {
value = code - 'A' + 10;
}
sum += value * factor;
}
int remainder = sum % 11;
char checkCode = checkCodes[11 - remainder];
return codes[codes.length - 1] == checkCode;
}
营业执照号码
//校验营业执照号码
public static boolean checkBizLicense(String bizLicense) {
//该算法主要通过一定的因子与各个字符进行运算得到一个校验码,并将其与倒数第二位字符进行比较从而判断营业执照号码是否合法。
// 需要注意的是,最后一位为1或2时,表示为个人所得税号码,不参与校验。
if (bizLicense == null || bizLicense.length() != 15) {
return false;
}
int[] factors = new int[]{1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28};
char[] checkCodes = "0123456789ABCDEFGHJKLMNPQRTUWXY".toCharArray();
int sum = 0;
for (int i = 0; i < bizLicense.length(); i++) {
char code = bizLicense.charAt(i);
if (i == 14 && (code == '1' || code == '2')) {
continue; // 最后一位为1或2,表示为个人所得税号码,不参与校验
}
int value = 0;
if (code >= '0' && code <= '9') {
value = code - '0';
} else if (code >= 'A' && code <= 'Z') {
value = code - 'A' + 10;
}
int factor = factors[i];
sum += value * factor;
}
int remainder = sum % 31;
char checkCode = checkCodes[remainder];
return bizLicense.charAt(14) == checkCode;
}
统一社会信用代码
//校验统一社会信用代码
public static boolean checkUSCC(String uscc) {
//统一社会信用代码(Unified Social Credit Code)是由国家工商行政管理总局颁布的企业唯一标识编码体系,编码规则为18位数字或字母
//该算法主要通过一定的因子与各个字符进行运算得到一个校验码,并将其与最后一位字符进行比较从而判断统一社会信用代码是否合法。
// 需要注意的是,第17位为校验码,由前面17位通过特定算法得出,而不是直接将某个字符作为校验码。
if (uscc == null || uscc.length() != 18) {
return false;
}
int[] factors = new int[]{1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28};
char[] checkCodes = "0123456789ABCDEFGHJKLMNPQRTUWXY".toCharArray();
int sum = 0;
for (int i = 0; i < uscc.length(); i++) {
char code = uscc.charAt(i);
int value = 0;
if (code >= '0' && code <= '9') {
value = code - '0';
} else if (code >= 'A' && code <= 'Z') {
value = code - 'A' + 10;
}
int factor = factors[i];
sum += value * factor;
}
int remainder = sum % 31;
char checkCode = checkCodes[remainder];
return uscc.charAt(17) == checkCode;
}
台胞大陆通行证
//校验台胞大陆通行证
public static boolean checkTaiwanCompatriotPermit(String permit) {
//该算法主要通过固定的因子与各个字符进行运算得到一个校验码,并将其与最后一位字符进行比较从而判断台胞证是否合法。
// 需要注意的是,第7位为字母(X、W、Y)时,分别代表“大陆地区”、“香港特别行政区”和“澳门特别行政区”,而不是做为校验码的一部分。
if (permit == null || permit.length() != 8) {
return false;
}
int[] factors = new int[]{7, 9, 10, 5, 8, 4, 2, 1};
char[] checkCodes = "0123456789XWY".toCharArray();
int sum = 0;
for (int i = 0; i < permit.length() - 1; i++) {
char code = permit.charAt(i);
int value = 0;
if (code >= '0' && code <= '9') {
value = code - '0';
} else if (code >= 'A' && code <= 'Z') {
value = code - 'A' + 10;
}
int factor = factors[i];
sum += value * factor;
}
int remainder = sum % 11;
char checkCode = checkCodes[remainder];
return permit.charAt(7) == checkCode;
}
以上数据识别均做过自测校验,如有存在不严谨的校验,劳烦大家指正!!!文章来源地址https://www.toymoban.com/news/detail-454288.html
到了这里,关于数据分类分级 数据识别-实现部分敏感数据识别的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!