All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hutool.core.util.DesensitizedUtil Maven / Gradle / Ivy

There is a newer version: 5.8.33
Show newest version
package cn.hutool.core.util;

/**
 * 脱敏工具类,支持以下类型信息的脱敏自动处理:
 *
 * 
    *
  • 用户ID
  • *
  • 中文名
  • *
  • 身份证
  • *
  • 座机号
  • *
  • 手机号
  • *
  • 地址
  • *
  • 电子邮件
  • *
  • 密码
  • *
  • 车牌
  • *
  • 银行卡号
  • *
* * @author dazer and neusoft and qiaomu * @since 5.6.2 */ public class DesensitizedUtil { /** * 支持的脱敏类型枚举 * * @author dazer and neusoft and qiaomu */ public enum DesensitizedType { /** * 用户id */ USER_ID, /** * 中文名 */ CHINESE_NAME, /** * 身份证号 */ ID_CARD, /** * 座机号 */ FIXED_PHONE, /** * 手机号 */ MOBILE_PHONE, /** * 地址 */ ADDRESS, /** * 电子邮件 */ EMAIL, /** * 密码 */ PASSWORD, /** * 中国大陆车牌,包含普通车辆、新能源车辆 */ CAR_LICENSE, /** * 银行卡 */ BANK_CARD, /** * IPv4地址 */ IPV4, /** * IPv6地址 */ IPV6, /** * 定义了一个first_mask的规则,只显示第一个字符。 */ FIRST_MASK, /** * 清空为null */ CLEAR_TO_NULL, /** * 清空为"" */ CLEAR_TO_EMPTY } /** * 脱敏,使用默认的脱敏策略 *
	 * DesensitizedUtil.desensitized("100", DesensitizedUtil.DesensitizedType.USER_ID)) =  "0"
	 * DesensitizedUtil.desensitized("段正淳", DesensitizedUtil.DesensitizedType.CHINESE_NAME)) = "段**"
	 * DesensitizedUtil.desensitized("51343620000320711X", DesensitizedUtil.DesensitizedType.ID_CARD)) = "5***************1X"
	 * DesensitizedUtil.desensitized("09157518479", DesensitizedUtil.DesensitizedType.FIXED_PHONE)) = "0915*****79"
	 * DesensitizedUtil.desensitized("18049531999", DesensitizedUtil.DesensitizedType.MOBILE_PHONE)) = "180****1999"
	 * DesensitizedUtil.desensitized("北京市海淀区马连洼街道289号", DesensitizedUtil.DesensitizedType.ADDRESS)) = "北京市海淀区马********"
	 * DesensitizedUtil.desensitized("[email protected]", DesensitizedUtil.DesensitizedType.EMAIL)) = "d*************@gmail.com.cn"
	 * DesensitizedUtil.desensitized("1234567890", DesensitizedUtil.DesensitizedType.PASSWORD)) = "**********"
	 * DesensitizedUtil.desensitized("苏D40000", DesensitizedUtil.DesensitizedType.CAR_LICENSE)) = "苏D4***0"
	 * DesensitizedUtil.desensitized("11011111222233333256", DesensitizedUtil.DesensitizedType.BANK_CARD)) = "1101 **** **** **** 3256"
	 * DesensitizedUtil.desensitized("192.168.1.1", DesensitizedUtil.DesensitizedType.IPV4)) = "192.*.*.*"
	 * 
* * @param str 字符串 * @param desensitizedType 脱敏类型;可以脱敏:用户id、中文名、身份证号、座机号、手机号、地址、电子邮件、密码 * @return 脱敏之后的字符串 * @author dazer and neusoft and qiaomu * @since 5.6.2 */ public static String desensitized(CharSequence str, DesensitizedUtil.DesensitizedType desensitizedType) { if (StrUtil.isBlank(str)) { return StrUtil.EMPTY; } String newStr = String.valueOf(str); switch (desensitizedType) { case USER_ID: newStr = String.valueOf(userId()); break; case CHINESE_NAME: newStr = chineseName(String.valueOf(str)); break; case ID_CARD: newStr = idCardNum(String.valueOf(str), 1, 2); break; case FIXED_PHONE: newStr = fixedPhone(String.valueOf(str)); break; case MOBILE_PHONE: newStr = mobilePhone(String.valueOf(str)); break; case ADDRESS: newStr = address(String.valueOf(str), 8); break; case EMAIL: newStr = email(String.valueOf(str)); break; case PASSWORD: newStr = password(String.valueOf(str)); break; case CAR_LICENSE: newStr = carLicense(String.valueOf(str)); break; case BANK_CARD: newStr = bankCard(String.valueOf(str)); break; case IPV4: newStr = ipv4(String.valueOf(str)); break; case IPV6: newStr = ipv6(String.valueOf(str)); break; case FIRST_MASK: newStr = firstMask(String.valueOf(str)); break; case CLEAR_TO_EMPTY: newStr = clear(); break; case CLEAR_TO_NULL: newStr = clearToNull(); break; default: } return newStr; } /** * 清空为空字符串 * * @return 清空后的值 * @since 5.8.22 */ public static String clear() { return StrUtil.EMPTY; } /** * 清空为{@code null} * * @return 清空后的值(null) * @since 5.8.22 */ public static String clearToNull() { return null; } /** * 【用户id】不对外提供userId * * @return 脱敏后的主键 */ public static Long userId() { return 0L; } /** * 定义了一个first_mask的规则,只显示第一个字符。
* 脱敏前:123456789;脱敏后:1********。 * * @param str 字符串 * @return 脱敏后的字符串 */ public static String firstMask(String str) { if (StrUtil.isBlank(str)) { return StrUtil.EMPTY; } return StrUtil.hide(str, 1, str.length()); } /** * 【中文姓名】只显示第一个汉字,其他隐藏为2个星号,比如:李** * * @param fullName 姓名 * @return 脱敏后的姓名 */ public static String chineseName(String fullName) { return firstMask(fullName); } /** * 【身份证号】前1位 和后2位 * * @param idCardNum 身份证 * @param front 保留:前面的front位数;从1开始 * @param end 保留:后面的end位数;从1开始 * @return 脱敏后的身份证 */ public static String idCardNum(String idCardNum, int front, int end) { //身份证不能为空 if (StrUtil.isBlank(idCardNum)) { return StrUtil.EMPTY; } //需要截取的长度不能大于身份证号长度 if ((front + end) > idCardNum.length()) { return StrUtil.EMPTY; } //需要截取的不能小于0 if (front < 0 || end < 0) { return StrUtil.EMPTY; } return StrUtil.hide(idCardNum, front, idCardNum.length() - end); } /** * 【固定电话 前四位,后两位 * * @param num 固定电话 * @return 脱敏后的固定电话; */ public static String fixedPhone(String num) { if (StrUtil.isBlank(num)) { return StrUtil.EMPTY; } return StrUtil.hide(num, 4, num.length() - 2); } /** * 【手机号码】前三位,后4位,其他隐藏,比如135****2210 * * @param num 移动电话; * @return 脱敏后的移动电话; */ public static String mobilePhone(String num) { if (StrUtil.isBlank(num)) { return StrUtil.EMPTY; } return StrUtil.hide(num, 3, num.length() - 4); } /** * 【地址】只显示到地区,不显示详细地址,比如:北京市海淀区**** * * @param address 家庭住址 * @param sensitiveSize 敏感信息长度 * @return 脱敏后的家庭地址 */ public static String address(String address, int sensitiveSize) { if (StrUtil.isBlank(address)) { return StrUtil.EMPTY; } int length = address.length(); return StrUtil.hide(address, length - sensitiveSize, length); } /** * 【电子邮箱】邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示,比如:d**@126.com * * @param email 邮箱 * @return 脱敏后的邮箱 */ public static String email(String email) { if (StrUtil.isBlank(email)) { return StrUtil.EMPTY; } int index = StrUtil.indexOf(email, '@'); if (index <= 1) { return email; } return StrUtil.hide(email, 1, index); } /** * 【密码】密码的全部字符都用*代替,比如:****** * * @param password 密码 * @return 脱敏后的密码 */ public static String password(String password) { if (StrUtil.isBlank(password)) { return StrUtil.EMPTY; } return StrUtil.repeat('*', password.length()); } /** * 【中国车牌】车牌中间用*代替 * eg1:null -》 "" * eg1:"" -》 "" * eg3:苏D40000 -》 苏D4***0 * eg4:陕A12345D -》 陕A1****D * eg5:京A123 -》 京A123 如果是错误的车牌,不处理 * * @param carLicense 完整的车牌号 * @return 脱敏后的车牌 */ public static String carLicense(String carLicense) { if (StrUtil.isBlank(carLicense)) { return StrUtil.EMPTY; } // 普通车牌 if (carLicense.length() == 7) { carLicense = StrUtil.hide(carLicense, 3, 6); } else if (carLicense.length() == 8) { // 新能源车牌 carLicense = StrUtil.hide(carLicense, 3, 7); } return carLicense; } /** * 【银行卡号脱敏】由于银行卡号长度不定,所以只展示前4位,后面的位数根据卡号决定展示1-4位 * 例如: *
{@code
	 *      1. "1234 2222 3333 4444 6789 9"    ->   "1234 **** **** **** **** 9"
	 *      2. "1234 2222 3333 4444 6789 91"   ->   "1234 **** **** **** **** 91"
	 *      3. "1234 2222 3333 4444 678"       ->    "1234 **** **** **** 678"
	 *      4. "1234 2222 3333 4444 6789"      ->    "1234 **** **** **** 6789"
	 *  }
* * @param bankCardNo 银行卡号 * @return 脱敏之后的银行卡号 */ public static String bankCard(String bankCardNo) { if (StrUtil.isBlank(bankCardNo)) { return bankCardNo; } bankCardNo = StrUtil.cleanBlank(bankCardNo); if (bankCardNo.length() < 9) { return bankCardNo; } final int length = bankCardNo.length(); final int endLength = length % 4 == 0 ? 4 : length % 4; final int midLength = length - 4 - endLength; final StringBuilder buf = new StringBuilder(); buf.append(bankCardNo, 0, 4); for (int i = 0; i < midLength; ++i) { if (i % 4 == 0) { buf.append(CharUtil.SPACE); } buf.append('*'); } buf.append(CharUtil.SPACE).append(bankCardNo, length - endLength, length); return buf.toString(); } /** * IPv4脱敏,如:脱敏前:192.0.2.1;脱敏后:192.*.*.*。 * * @param ipv4 IPv4地址 * @return 脱敏后的地址 */ public static String ipv4(String ipv4) { return StrUtil.subBefore(ipv4, '.', false) + ".*.*.*"; } /** * IPv6脱敏,如:脱敏前:2001:0db8:86a3:08d3:1319:8a2e:0370:7344;脱敏后:2001:*:*:*:*:*:*:* * * @param ipv6 IPv6地址 * @return 脱敏后的地址 */ public static String ipv6(String ipv6) { return StrUtil.subBefore(ipv6, ':', false) + ":*:*:*:*:*:*:*"; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy