首页

关于Java通过掩码*对客户姓名手机号等敏感数据进行处理CustomerSecretDataFilter类源码示例

标签:敏感数据过滤,脱敏,日志数据过滤,客户手机号,客户姓名,字符串过滤转码     发布时间:2018-06-07   

一、前言

关于Java在实现涉及用户/客户敏感数据(如手机号、姓名等)打印输出的时候,通常需要将其转换为掩码”*“处理,下面通过具体的源码示例进行说明。

二、示例说明

下面示例依赖fastjson

package test;@b@@b@import java.util.regex.Matcher;@b@import java.util.regex.Pattern;@b@import org.apache.commons.lang.StringUtils;@b@import com.alibaba.fastjson.JSON;@b@import com.alibaba.fastjson.JSONObject;@b@@b@public class CustomerSecretDataFilter {@b@	@b@	private static Pattern pattern = Pattern.compile("[0-9a-zA-Z]");@b@	//手机号掩码字段@b@	private static String CUST_PHONE="customerPhone,mobile,MOBILE";@b@	//客户姓名掩码字段@b@	private static String CUST_NAME="customerName,custName,CUST_NAME,clientName";@b@	@b@	/**@b@     * 客户手机号,处理日志字符串,返回脱敏后的字符串@b@     * @param msg@b@     * @return@b@     */@b@	private static String maskCustPhoneMsg(final String message){    @b@        String msg = handleMsg(CUST_PHONE,message);@b@        return msg;@b@    }@b@    /**@b@     * 客户姓名,处理日志字符串,返回脱敏后的字符串@b@     * @param msg@b@     * @return@b@     */@b@    private static String maskCustNameMsg(final String message){    @b@        String msg = handleMsg(CUST_NAME,message);@b@        return msg;@b@    }@b@    @b@    @b@    /**@b@     * 处理日志字符串,返回脱敏后的字符串@b@     * @param msg@b@     * @return@b@     */@b@    private static String handleMsg(final String handleAttr,final String fullText){@b@        @b@        String msg = new String(fullText);@b@        @b@        //处理字符串@b@        if(handleAttr!=null && handleAttr.length()>0){@b@            @b@            String[] keyArr = handleAttr.split(",");@b@            for(String key: keyArr){@b@                // 找key@b@                int index= -1; @b@                do{@b@                    index = msg.indexOf(key, index+1);@b@                    if(index!=-1){ @b@                        // 判断key是否为单词字符@b@                        if(isWordChar(msg,key,index)){@b@                            continue;@b@                        }@b@                        // 确定是单词无疑....................................@b@                        // 寻找值的开始位置.................................@b@                        int valueStart = getValueStartIndex(msg,index + key.length());@b@                        @b@                        //查找值的结束位置(逗号,分号)........................@b@                        int valueEnd = getValuEndEIndex(msg,valueStart);@b@                        @b@                        // 对获取的值进行脱敏 @b@                        String subStr = msg.substring(valueStart, valueEnd);@b@                        if(CUST_PHONE.equals(handleAttr)){@b@                        	subStr = tuominPhone(subStr);@b@                        }@b@                        if(CUST_NAME.equals(handleAttr)){@b@                        	subStr = replaceMask(subStr, 1, 0, "*");@b@                        }@b@                        @b@                        ///////////////////////////@b@                        msg = msg.substring(0,valueStart) + subStr + msg.substring(valueEnd);@b@                    }@b@                }while(index!=-1);@b@                @b@            }@b@        }@b@        @b@        @b@        return msg;@b@    }@b@    @b@   @b@    /**@b@     * 判断从字符串msg获取的key值是否为单词 , index为key在msg中的索引值@b@     * @return@b@     */@b@    private static boolean isWordChar(String msg,String key, int index){@b@        @b@        // 必须确定key是一个单词............................@b@        if(index!=0){ //判断key前面一个字符@b@            char preCh = msg.charAt(index-1);@b@            Matcher match = pattern.matcher(preCh+"");@b@            if(match.matches()){@b@                return true;@b@            }@b@        }@b@        //判断key后面一个字符@b@        char nextCh = msg.charAt(index+key.length());@b@        Matcher match = pattern.matcher(nextCh+"");@b@        if(match.matches()){@b@            return true;@b@        }@b@        @b@        return false;@b@        @b@    }@b@    @b@    /**@b@     * 获取value值的开始位置@b@     * @param msg 要查找的字符串@b@     * @param valueStart 查找的开始位置@b@     * @return@b@     */@b@    private static int getValueStartIndex(String msg, int valueStart ){@b@        // 寻找值的开始位置.................................@b@        do{@b@            char ch = msg.charAt(valueStart);@b@            if(ch == ':' || ch == '='){ // key 与 value的分隔符@b@                valueStart ++;@b@                ch = msg.charAt(valueStart);@b@                if(ch == '"'){@b@                    valueStart ++;@b@                }@b@                break;    //找到值的开始位置@b@            }else{@b@                valueStart ++;@b@            }@b@            @b@        }while(true);@b@        return valueStart;@b@    }@b@    @b@    /**@b@     * 获取value值的结束位置@b@     * @return@b@     */@b@    private static int getValuEndEIndex(String msg,int valueEnd){@b@        @b@        do{@b@            if(valueEnd == msg.length()){@b@                break;@b@            }@b@            char ch = msg.charAt(valueEnd);@b@            @b@            if(ch == '"'){ // 引号时,判断下一个值是结束,分号还是逗号决定是否为值的结束@b@                if(valueEnd+1 == msg.length()){@b@                    break;@b@                }@b@                char nextCh = msg.charAt(valueEnd+1);@b@                if(nextCh ==';' || nextCh == ',' || nextCh == '}' || nextCh == ']'){@b@                    // 去掉前面的 \  处理这种形式的数据 "account_num\\\":\\\"6230958600001008\\\"@b@                    while(valueEnd>0 ){@b@                        char preCh = msg.charAt(valueEnd-1);@b@                        if(preCh != '\\'){@b@                            break;@b@                        }@b@                        valueEnd--;@b@                    }@b@                    break;@b@                }else{@b@                    valueEnd ++;@b@                }@b@            }else if (ch ==';' || ch == ','){@b@                break;@b@            }else{@b@                valueEnd ++;@b@            }@b@            @b@        }while(true);@b@        @b@        return valueEnd;@b@    }@b@    @b@	/**@b@	 * 公用方法,以后可以使用这个方法进行掩码@b@	 * @param str@b@	 * @param start@b@	 * @param end@b@	 * @param placeStr@b@	 * @return@b@	 */@b@    private static String replaceMask(String str, int start, int end, String placeStr){@b@		if(StringUtils.isBlank(str)){@b@			return "";@b@		}@b@		if(start < 0 || end < 0){@b@			return str;@b@		}@b@		if(StringUtils.isBlank(placeStr)){@b@			placeStr = "*";@b@		}@b@		return str.replaceAll("(?<=[\\S]{"+ start +"})\\S(?=[\\S]{"+ end +"})", placeStr);@b@	}@b@    @b@    private static String tuominPhone(String submsg){@b@@b@        StringBuffer sbResult = new StringBuffer();@b@        if(submsg!=null && submsg.length()>0){@b@            int len = submsg.length();@b@            if(len >= 4){ //4位及以上的    隐掉中间4位@b@                for(int i = len-1;i>=0;i--){@b@                    if(len-i<5 || len-i>8){@b@                        sbResult.insert(0, submsg.charAt(i));@b@                    }else{@b@                        sbResult.insert(0, '*');@b@                    }@b@                }@b@            }else{ //4位以下的全部使用 *@b@                for(int i =0;i<len;i++){@b@                    sbResult.append('*');@b@                }@b@            }@b@        }@b@        return sbResult.toString();@b@    }@b@	@b@     @b@    @b@    public static String maskSecretLog(final Object obj){@b@        //对象转json串@b@    	String result = JSON.toJSONString(obj);@b@    	try{@b@    	   result=maskCustPhoneMsg(result);@b@		   result=maskCustNameMsg(result);@b@    	}catch(Exception e){@b@    		e.printStackTrace();@b@    	}@b@    	return result;@b@    }@b@    public static String maskSecretLog(final String str){@b@        //对象赋值@b@    	String result = str;@b@    	try{@b@    	   result=maskCustPhoneMsg(result);@b@		   result=maskCustNameMsg(result);@b@    	}catch(Exception e){@b@    		e.printStackTrace();@b@    	}@b@    	return result;@b@    }@b@    @b@    public static   void  main(String[] args){@b@    	@b@    	 System.out.println(maskSecretLog(new customer("159215401234","小木人印象")));@b@    	 @b@    	 System.out.println(maskSecretLog(JSONObject.toJSONString(new customer("159215401235","小木人印象2"))));@b@    	@b@    	@b@    }@b@    @b@    static  class  customer{@b@    	@b@    	private  String customerPhone;@b@    	@b@    	private  String customerName;@b@@b@		public customer(String customerPhone, String customerName) {@b@			super();@b@			this.customerPhone = customerPhone;@b@			this.customerName = customerName;@b@		}@b@    	@b@    	public String getCustomerPhone() {@b@			return customerPhone;@b@		}@b@@b@		public void setCustomerPhone(String customerPhone) {@b@			this.customerPhone = customerPhone;@b@		}@b@@b@		public String getCustomerName() {@b@			return customerName;@b@		}@b@@b@		public void setCustomerName(String customerName) {@b@			this.customerName = customerName;@b@		}@b@    	@b@    }@b@@b@}

控制台结果

{"customerName":"小****","customerPhone":"1592****1234"}@b@{"customerName":"小*****","customerPhone":"1592****1235"}
  • ◆ 相关内容