【HUAWEI OJ 题库】日志敏感信息屏蔽

题目描述

先给一个列表words,和一个日志信息的字符串,请对日志信息中的敏感信息进行屏蔽。

日志信息字符串是以,分割的[key:value]格式表示的字符串,value中不会包括字符,:,以key值区分衣服为敏感信息。

敏感信息:其key值有两类,第1类是出现在words中的,第2类是缺省关键字passwordpwd(注:第2类优先)。

敏感信息屏蔽规则:

  1. key为 passwordpwd 的:对应的value统一用6个*代替。
  2. key在words中,且以 IP (不区分大小写)结尾的:对应value中ip地址中间两段分别用三个 * 代替(不用考虑IPv6格式),用例保证IP格式的合法性。
  3. key在words中,且以非 IP 结尾的:仅需对value中最右侧的长度(L)大于等于4,且连续为数字的子串进行屏蔽,从倒数第L/4+1个数字字符开始(比如L为9,从倒数第三个开始),从右到左对中间的L/2个字符用 * 代替。

非敏感信息处理规则: 原样输出。

注:关键字匹配时不区分大小写,输出时保持大小写不变。

解答要求

时间限制:1000ms,内存限制:256MB

输入

首行为一个正整数N,表示敏感信息关键字的个数,取值范围:[0, 50]。

第二行为一个长度为N的一维数组,表示敏感信息关键字列表words,每个关键字的长度范围:[0, 15]。

第三行为一个字符串,表示待处理的日志信息,字符串长度范围:[1, 200]。

输出

一个字符串,表示屏蔽后的日志信息。

样例

输入样例

5
IMSI CellID UserIP CID UID
Apn:cnet,Qos:121212121212,CellID:4600175319,Imsi:460019852146201,GWIP:1.1.1.1,UserIp:2.2.2.2,CID:854710-336985-852,UID:1-2-3-4,pwd:huawei7410

输出样例

Apn:cnet,Qos:121212121212,CellID:460*****19,Imsi:46001*******201,GWIP:1.1.1.1,UserIp:2.***.***.2,CID:854710-33***5-852,UID:1-2-3-4,pwd:******

编码实现(java)

    public static void main(String[] args) {
        String[] keys = new String[]{"IMSI", "CellID", "UserIP", "CID", "UID"};
        String log = "Apn:cnet,Qos:121212121212,CellID:4600175319,Imsi:460019852146201,GWIP:1.1.1.1,UserIp:2.2.2.2,CID:854710-336985-852,UID:1-2-3-4,pwd:huawei7410";
        System.out.println(logAnonymize(keys, log));
    }

    private static String logAnonymize(String[] keys, String log) {
        // 敏感信息关键字转小写
        List<String> words = Arrays.stream(keys).map(String::toLowerCase).collect(Collectors.toList());
        String[] logEntries = log.split(",");
        StringBuilder maskedLog = new StringBuilder();
        for (String entry : logEntries) {
            String[] keyValue = entry.split(":");
            String key = keyValue[0].trim();
            String value = keyValue[1].trim();
            if (key.equalsIgnoreCase("password") || key.equalsIgnoreCase("pwd")) {
                value = "******";
            } else if (words.contains(key.toLowerCase())) {
                if (key.toLowerCase().endsWith("ip")) {
                    String[] ipSegments = value.split("\\.");
                    if (ipSegments.length == 4) {
                        ipSegments[1] = "***";
                        ipSegments[2] = "***";
                        value = String.join(".", ipSegments);
                    }
                } else {
                    int length = value.length();
                    int startIndex = -1; // 连续数字的子串末尾下标
                    int count = 0; // 连续数字的个数
                    for (int i = length - 1; i >= 0; i--) {
                        if (Character.isDigit(value.charAt(i))) { // 判断是否为数字
                            if (startIndex == -1) {
                                startIndex = i;
                            }
                            count++;
                        } else {
                            if (count >= 4) { // 为非数字时 判断当前子串是否满足条件
                                break;
                            } else {
                                startIndex = -1;
                                count = 0;
                            }
                        }
                    }
                    if (startIndex != -1 && count >= 4) {
                        // 从倒数L/4+1个数字字符开始 = startIndex-(L/4+1)+1 = startIndex - count / 4
                        int hideEndIndex = startIndex - count / 4;
                        // 屏蔽中间的L/2个字符 由于hideEndIndex本身也在屏蔽范围内 故hideStartIndex = hideEndIndex - count / 2 + 1
                        int hideStartIndex = hideEndIndex - count / 2 + 1;
                        StringBuilder stringBuilder = new StringBuilder(value);
                        for (int i = hideStartIndex; i <= hideEndIndex; i++) {
                            stringBuilder.setCharAt(i, '*');
                        }
                        value = stringBuilder.toString();
                    }
                }
            }
            maskedLog.append(key).append(":").append(value).append(",");
        }
        String maskedLogString = maskedLog.toString();
        if (maskedLogString.endsWith(",")) {
            maskedLogString = maskedLogString.substring(0, maskedLogString.length() - 1);
        }
        return maskedLogString;
    }

输出结果

Apn:cnet,Qos:121212121212,CellID:460*****19,Imsi:46001*******201,GWIP:1.1.1.1,UserIp:2.***.***.2,CID:854710-33***5-852,UID:1-2-3-4,pwd:******

Process finished with exit code 0
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值