数据分类分级 数据识别-实现部分敏感数据识别

这篇具有很好参考价值的文章主要介绍了数据分类分级 数据识别-实现部分敏感数据识别。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前面针对数据安全-数据分类分级方案设计做了分析讲解,以及针对日期类型的数据识别做了讲解(数据分类分级 数据识别-识别日期类型数据),也是正则表达式方式,这里不做赘述

敏感数据识别

通过内置数据识别规则或用户数据识别规则,对其结构化表进行整体扫描,自动识别敏感数据,进行分级
数据分类分级 数据识别-实现部分敏感数据识别

敏感字段

统一社会信用代码,车辆识别代码,营业执照号码,税务登记证号码,组织机构代码,图片,日期,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等)确定其对应的校验规则。具体来说,它会通过调用一系列子方法,先根据信用卡号的前几位数字确定信用卡类型,再根据该类型的规则进行校验,最后返回一个布尔值表示是否有效。校验规则通常包括以下几个方面:

  1. 根据不同类型的信用卡确定长度和开头数字等规则。
  2. 使用 Luhn 算法对信用卡号进行校验。Luhn 算法是一种简单的校验算法,其原理是将信用卡号每一位上的数字分别乘以 2 或 1,并将乘积的个位数和十位数相加,最后将所有数字相加并求余数,如果余数为 0,则该信用卡号有效。
  3. 根据特殊规则进行校验,如根据信用卡号的长度和特定数字的组合方式等。

总之,CreditCardValidator.genericCreditCardValidator()
的原理就是根据信用卡号的类型和规则,通过各种校验方式来判断信用卡号是否有效。

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模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【转】数据的分类分级简介

    原文链接:https://blog.csdn.net/watson2017/article/details/126388340 1、数据分类分级实施标准 2021年12月31号,全国信息安全标准化技术委员会秘书处发布了《网络安全标准实践指南——网络数据分类分级指引》,给出了数据分类分级的原则、框架和方法。 2、数据分类分级定义 数据分类

    2024年02月15日
    浏览(43)
  • 【转】数据分类分级产品工具

    原文链接:https://blog.csdn.net/weixin_52069830/article/details/124553895 前言 数据分类分级,作为数据安全治理的基础和首要工作,重要性无需赘言,关于数据分类分级的解决方案请看金融数据安全分类分级解决方案,可以了解下整体思路和基本概念。 《数据安全法》、《个人信息保护

    2024年02月03日
    浏览(34)
  • 什么是数据分类分级?

    自《数据安全法》明确对数据实行分类分级保护后,国家和地方都在加紧该项工作的进行。据行业专家透露,目前国家标准《信息安全技术重要数据识别指南》已经到送审稿阶段,而国标《信息安全技术重要数据处理安全要求》也已完成草稿,正在立项过程之中。梳理发现,

    2024年02月02日
    浏览(38)
  • 数据分类分级产品,一文详解

    前言 1、产品介绍 2、技术原理 3、业务流程 4、部署方式   4.1常规部署   4.2docker镜像部署 5、产品主要功能   5.1数据资产扫描   5.2敏感数据自动发现   5.3数据分类分级管理   5.4分类分级结果导出 6、产品价值 7、安全服务 8、技术发展趋势   8.1具备机器学习和数据挖掘技术

    2024年02月09日
    浏览(48)
  • 大数据的分类分级管理

            为了公司给的师带徒,为培训写点材料。让徒弟做事情要有章法,有行业视野,知道方向和资料从哪里去找。         要管理企业的大数据,从什么地方开始呢?首先应该完成企业数据的分类、分级,或者参考分类去找出企业相关的数据条目。         作为工业企

    2024年03月14日
    浏览(120)
  • 数据安全-数据分类分级方案设计

    前面针对数据分类分级做了较为系统性的调研分析报告,具体内容可点击,不再做赘述: 数据安全-数据分类分级调研分析报告 通过前期市场调研与分析,发现已经有多家企业在数据分类分级方向发力,国家政策也是21年才正式发布,市场还处于早期阶段,多家产品也是近一

    2024年01月16日
    浏览(42)
  • 一文读懂数据安全分级分类

    目录 为什么要分级分类? 通用数据分级分类框架 数据分类 数据分类的常用方法 数据分类流程 数据分级 数据分级的常用方法 数据定级流程 行业数据安全分级分类指南 金融行业 电信行业 政务数据 健康医疗 企业实践 附录:数据分级分类大合集 数据分类为信息安全管理提供

    2023年04月26日
    浏览(48)
  • 网络安全合规-数据安全分类分级

    数据安全是指保护数据免受未经授权的访问、使用、泄露、破坏或篡改的措施。数据安全包括物理安全、网络安全、应用程序安全、数据备份和恢复等方面。 数据分级分类是指根据数据的重要性和敏感程度,将数据划分为不同的级别,并根据不同级别的数据制定不同的安全措

    2024年02月11日
    浏览(42)
  • 芳禾数据CTO李明:数据分类分级与治理驱动下的应用革命丨数据猿专访

    ‍数据智能产业创新服务媒体 ——聚焦数智 · 改变商业 我们进入数字化时代,数据已经变得比任何时候都更加关键。每天,我们都在生成、处理和存储海量的数据,这些数据在企业决策、市场研究、产品开发等方面扮演着重要的角色。然而,数据的价值并非总是立即可见的

    2024年02月10日
    浏览(44)
  • 安全牛《数据分类分级自动化建设指南》发布|美创入选代表厂商,分享智能化探索

    近日,安全牛发布《数据分类分级自动化建设指南》研究报告,对数据分类分级的主要技术、实施要点、选型指导、发展趋势等展开深入探讨,为各行业数据分类分级自动化工作落地提供帮助与指引。 美创科技被列为代表推荐厂商, 落地案例—农商行基于分类分级的数据安

    2024年02月03日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包