iT邦幫忙

2024 iThome 鐵人賽

DAY 5
0

發表到這裡,除了Day 1,每一篇幾乎與資安弱掃扯上關係,隱碼也不例外,不能外洩個資,舉凡身份證號、手機號碼、姓名、信用卡號、E-Mail和生日都算,也因此寫出隱碼公用程式,提供兩個Method。

  • hiddenCode:針對傳進來的值進行隱碼
  • hiddenByJSON:針對JSON的key,對其value進行隱碼
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SensitivityUtil {
	public enum SensitivityType {
		ID,
		PHONE,
		CNAME,
		CREDIT_CARD,
		EMAIL,
		BIRTHDAY
	}
	
	public static String hiddenCode (SensitivityType stype, String orig) {
		if (orig == null || orig.length() < 2) return orig;
		switch(stype) {
		case ID:      // 身份證號
			return orig.substring(0, 2) + new String(new char[orig.length() - 4]).replace("\0", "*") +  orig.substring(orig.length() - 2);
		case PHONE:  // 手機、電話
			return orig.matches("^\\+\\d{4,}") ? orig.replaceAll("(?<=[^#-]\\d{7})\\d", "*") : orig.replaceAll("(?<=[^#-]\\d{4})\\d", "*");
		case CNAME:  // 中文姓名
			if (orig.length() == 2) {
				return orig.substring(0, 1) +  "〇" +  orig.substring(orig.length() - 1);
			}
			return orig.substring(0, 1) + new String(new char[orig.length() - 2]).replace("\0", "〇") +  orig.substring(orig.length() - 1);
		case CREDIT_CARD:  // 信用卡號
			return orig.substring(0, 4) + new String(new char[orig.length() - 8]).replace("\0", "X") + orig.substring(orig.length() - 4);
		case EMAIL:  // 電子郵件
			return orig.replaceAll("(?<=.{3}).(?=[^@]*?@)", "*");
		case BIRTHDAY:  // 生日
			return orig.replaceFirst("(\\d{2})\\d{2}", "$1**").replaceFirst("\\d{2}$", "**");
		}
		return orig;
	}
	
	public String hiddenByJSON(String orig, Map<String, SensitivityType> hidMap) {
		if (orig == null || orig.length() < 2) return orig;
		for (Map.Entry<String, SensitivityType> entry : hidMap.entrySet()) {
			String keyName = entry.getKey();
			SensitivityType sType = entry.getValue();
			String origPat = "\"" + keyName + "\":\"(.+?)\"";
			Pattern pat = Pattern.compile(origPat);
			Matcher mat = pat.matcher(orig);
			if (mat.find()) {
				String hidCode = hiddenCode(sType, mat.group(1));
				orig = orig.replaceFirst(origPat, "\"" + keyName + "\":\"" + hidCode + "\"");
			}
		}
		
		return orig;
		
	}
	
	public static void main(String[] args) {
		System.out.println(SensitivityUtil.hiddenCode(SensitivityUtil.SensitivityType.CNAME, "鐵人賽"));
		System.out.println(SensitivityUtil.hiddenCode(SensitivityUtil.SensitivityType.CNAME, "張菲"));
		System.out.println(SensitivityUtil.hiddenCode(SensitivityUtil.SensitivityType.CNAME, "谷辣斯.尤達卡"));
		System.out.println(SensitivityUtil.hiddenCode(SensitivityUtil.SensitivityType.CREDIT_CARD, "5130123456783666"));
		System.out.println(SensitivityUtil.hiddenCode(SensitivityUtil.SensitivityType.EMAIL, "tsaijemmy@google.com"));
		System.out.println(SensitivityUtil.hiddenCode(SensitivityUtil.SensitivityType.BIRTHDAY, "1970-01-01"));
		SensitivityUtil util = new SensitivityUtil();
		Map<String, SensitivityType> hidMap = new HashMap<String, SensitivityType>();
		hidMap.put("CustID", SensitivityUtil.SensitivityType.ID);
		hidMap.put("PhoneNumber", SensitivityUtil.SensitivityType.PHONE);
		String orig = "{\"header\":{\"InputClass\":\"com.company.biz.LoginVO\",\"TxnCode\":\"BIZ000\",\"StampTime\":true,\"TXN_DATA\":{},\"CustID\":\"A123456789\",\"PhoneNumber\":\"0932123456\",\"Browser\":{\"chrome\":\"100.0.4896.127\"}},\"body\":{\"pageCount\":10}}";
		System.out.println(util.hiddenByJSON(orig, hidMap));
		String[] strPhoneNumbers = {
                "0912345678",
                "02-77123456",
                "+886912345678",
                "(02)77123456",
                "(02)77123456#12345",
                "02-77123456-12345",
        };
		for(String phoneNumber : strPhoneNumbers) {
			String maxNum = Arrays.asList(phoneNumber.split("\\D")).stream().max(Comparator.comparingInt(String::length)).get();
			int cnt = (int) maxNum.chars().filter(Character::isDigit).count();
            System.out.println( phoneNumber + " : " +  SensitivityUtil.hiddenCode(SensitivityUtil.SensitivityType.PHONE, phoneNumber));
        }
	}
}

從java main測試得到的結果如下:

鐵〇賽
張〇菲
谷〇〇〇〇〇卡
5130XXXXXXXX3666
tsa******@google.com
19**-01-**
{"header":{"InputClass":"com.company.biz.LoginVO","TxnCode":"BIZ000","StampTime":true,"TXN_DATA":{},"CustID":"A1******89","PhoneNumber":"09321*****","Browser":{"chrome":"100.0.4896.127"}},"body":{"pageCount":10}}
0912345678 : 09123*****
02-77123456 : 02-77123***
+886912345678 : +8869123*****
(02)77123456 : (02)7712****
(02)77123456#12345 : (02)7712****#12345
02-77123456-12345 : 02-77123***-12345

上一篇
Java在漢字、全形字的偵測
下一篇
關於CSV檔裡的英文地址
系列文
正則!好好表達30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言