关闭

《高效精准》敏感字&词过滤

标签: 算法敏感字词过滤
2951人阅读 评论(9) 收藏 举报
分类:
在网上看到的大部分采用DFA算法,我看了之后感觉做得有些复杂了,DFA实现思路如下:
1:DFA采用Map的hash机制,将敏感词单个拆分,以第1个字符为key,其他值依旧使用map相连,形成了大map套用小map..

2:遍历需要过滤的字符串,获取每一个字符,根据get(key)来检测是否为敏感词。

我最开始是想到用正则来提取数据中的敏感数据,然后获取敏感字所在索引位置,再利用StringBuilder.replace(start,end,str)来替换,但经过测试发现使用正则有2个问题:
1:因为是正则要整串匹配,所以效率慢,同样3318个字符,平均在50毫秒以上
2:和敏感词与正则数据会产生冲突
所以就选择另一种思路:
1:遍历敏感词库,采用indexOf()来循环查询信息中是否含有此敏感数据
2:利用hashMap的来记录敏感在信息的key(起始位置)和最大的value(结束位置)
3:然后再遍历hashMap,得到每一组的start,end  再使用StringBuilder.replace(start,end,str)来替换敏感信息

4:被过滤的信息有3318个字符,平均在3~5毫秒内完成。

测试代码

   

	public void demo3(){
		SensitiveWord sw = new SensitiveWord("CensorWords1.txt");
		sw.InitializationWork();
		long startNumer = System.currentTimeMillis();
		String str = "太多的伤yuming感情怀也许只局限于饲养基地 荧幕中的情节,主人公尝试着去用某种方式渐渐的很潇洒地释自杀指南怀那些自己经历的伤感。"
				+ "然后法轮功 我们的扮演的角色就是跟随着主人yum公的喜红客联盟 怒于饲养基地 荧幕中的情节,主人公尝试着去用某种方式渐渐的很潇洒地释自杀指南怀那些自己经历的伤感。"
				+ "然后法轮功 我们的扮演的角色就是跟随着主人yum公的喜红客联盟 怒哀20于饲养基地 荧幕中的情节,主人公尝试着去用某种方式渐渐的很潇洒地释自杀指南怀那些自己经历的伤感。"
				+ "然后法轮功 我们的扮演的角色就是跟随着主人yum公的喜红客联盟 怒哀20哀2015/4/16 20152015/4/16乐而过于牵强的把自己的情感也附加于银幕情节中,然后感动就流泪,"
				+ "关, 人, 流, 电, 发, 情, 太, 限, 法轮功, 个人, 经, 色, 许, 公, 动, 地, 方, 基, 在, 上, 红, 强, 自杀指南, 制, 卡, 三级片, 一, 夜, 多, 手机, 于, 自,"
				+ "难过就躺在某一个人的怀里尽情的阐述心扉或者手机卡复制器一个人一杯红酒一部电影在夜三级片 深人静的晚上,关上电话静静的发呆着。";
		System.out.println("被检测字符长度:"+str.length());
		str = sw.filterInfo(str);
		long endNumber = System.currentTimeMillis();
		System.out.println("耗时(毫秒):"+(endNumber-startNumer));
		System.out.println("过滤之后:"+str);
	}

运行结果

    

代码如下:
       
package com.amov.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

/**
 *  敏感词过滤 工具类
 *  
 * @author hubiao
 * @version 0.1
 * @CreateDate 2015年4月16日 15:28:32
 */
public class SensitiveWord {
	private StringBuilder replaceAll;//初始化
	private String encoding = "UTF-8";
	private String replceStr = "*";
	private int replceSize = 500;
	private String fileName = "CensorWords.txt";
	private List<String> arrayList;
	
	/**
	 * 文件要求路径在src或resource下,默认文件名为CensorWords.txt
	 * @param fileName 词库文件名(含后缀)
	 */
	public SensitiveWord(String fileName)
	{
		this.fileName = fileName;
	}
	
	/**
	 * @param replceStr 敏感词被转换的字符
	 * @param replceSize 初始转义容量
	 */
	public SensitiveWord(String replceStr,int replceSize)
	{
		this.replceStr = fileName;
		this.replceSize = replceSize;
	}
	
	public SensitiveWord()
	{
	}
	/**
	 * @param str 将要被过滤信息
	 * @return 过滤后的信息
	 */
	public String filterInfo(String str)
	{
		StringBuilder buffer = new StringBuilder(str);
		HashMap<Integer, Integer> hash = new HashMap<Integer, Integer>(arrayList.size());
		String temp;
		for(int x = 0; x < arrayList.size();x++)
		{
			temp = arrayList.get(x);
			int findIndexSize = 0;
			for(int start = -1;(start=buffer.indexOf(temp,findIndexSize)) > -1;)
			{
				findIndexSize = start+temp.length();//从已找到的后面开始找
				Integer mapStart = hash.get(start);//起始位置
				if(mapStart == null || (mapStart != null && findIndexSize > mapStart))//满足1个,即可更新map
				{
					hash.put(start, findIndexSize);
				}
			}
		}
		Collection<Integer> values = hash.keySet();
		for(Integer startIndex : values)
		{
			Integer endIndex = hash.get(startIndex);
			buffer.replace(startIndex, endIndex, replaceAll.substring(0,endIndex-startIndex));
		}
		hash.clear();
		return buffer.toString();
	}
	/**
	 *   初始化敏感词库
	 */
	public void InitializationWork()
	{
		replaceAll = new StringBuilder(replceSize);
		for(int x=0;x < replceSize;x++)
		{
			replaceAll.append(replceStr);
		}
		//加载词库
		arrayList = new ArrayList<String>();
		InputStreamReader read = null;
		BufferedReader bufferedReader = null;
		try {
			read = new InputStreamReader(SensitiveWord.class.getClassLoader().getResourceAsStream(fileName),encoding);
			bufferedReader = new BufferedReader(read);
			for(String txt = null;(txt = bufferedReader.readLine()) != null;){
				if(!arrayList.contains(txt))
					arrayList.add(txt);
		    }
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				if(null != bufferedReader)
				bufferedReader.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(null != read)
				read.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	public StringBuilder getReplaceAll() {
		return replaceAll;
	}
	public void setReplaceAll(StringBuilder replaceAll) {
		this.replaceAll = replaceAll;
	}
	public String getReplceStr() {
		return replceStr;
	}
	public void setReplceStr(String replceStr) {
		this.replceStr = replceStr;
	}
	public int getReplceSize() {
		return replceSize;
	}
	public void setReplceSize(int replceSize) {
		this.replceSize = replceSize;
	}
	public String getFileName() {
		return fileName;
	}
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	public List<String> getArrayList() {
		return arrayList;
	}
	public void setArrayList(List<String> arrayList) {
		this.arrayList = arrayList;
	}
	public String getEncoding() {
		return encoding;
	}
	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}
	
}

2
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

使用log4j2实现日志数据脱敏

我们在JAVA项目中,通常会使用日志组件打印日志。但是,在日志中不能打印出用户的敏感信息。比如账户号码、群组号码、密码、IP地址等。而在当前的日志中,存在了大量这样的信息,用于定位问题。我们使用的是l...
  • dongping8887
  • dongping8887
  • 2017-05-08 23:29
  • 2002

关于实现log4j2日志脱敏的一种方案

log4j2日志脱敏方案
  • lrcxl
  • lrcxl
  • 2017-12-05 20:44
  • 286

开源机器学习项目的简单介绍

机器学习开源项目的简单介绍 摘要: 2016 和 2017 年对机器学习来说都是令人兴奋的,机器学习领域在 2016 年取得了重大的进展,2017 年,热度继续上升......2016 年,似乎所有巨...
  • English0523
  • English0523
  • 2017-11-16 17:40
  • 478

8种常见机器学习算法比较

8种常见机器学习算法比较 2016-08-04 17:46 转载 陈圳 0条评论 雷锋网(搜索“雷锋网”公众号关注)按:本文转自刘志伟责编,在机器学习中选择一个恰当的...
  • Real_Myth
  • Real_Myth
  • 2016-08-22 09:33
  • 1989

DFA敏感词过滤算法

运用DFA算法加密。 首先我先对敏感词库初始化,若我的敏感词库为 冰毒 白粉 大麻 大坏蛋 初始化之后得到的是下面这样。: {冰={毒={isEnd=1}, isEnd=0}, 白={粉={isEnd...
  • qq_33101675
  • qq_33101675
  • 2017-09-04 14:12
  • 208

java过滤敏感词替换**

import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStream; import ja...
  • liang_love_java
  • liang_love_java
  • 2014-06-06 11:51
  • 1722

Filter高级开发(二)——实现敏感字符过滤功能

在实际开发中,我们如果真正要做一个上线的网站,就要考虑到过滤敏感字符(敏感词)。 敏感词可分为三大类: 禁用词,我们用数字1来表示。 审核词,我们用数字2来表示。 替换词,我们用数字3来表示。 为了...
  • yerenyuan_pku
  • yerenyuan_pku
  • 2016-09-09 16:39
  • 2420

JavaWeb-过滤器Filter学习(四)敏感词过滤实例

通过Filter来实现留言板的敏感词过滤…思路很简单,我们这里的敏感词是直接先放进去的,实际项目中,肯定是存在数据库中。在Filter 过滤器中,我们先拿到用户提交的留言,如果出现了敏感词,我们就用*...
  • qq_26525215
  • qq_26525215
  • 2016-08-18 17:29
  • 7281

文字识别系统助力AI,快速高效超精准 | 支持免费测试

大多数人了解的OCR应用只是冰山一角,根据市场的需求OCR应用划分很详细,智慧认知广泛满足了企业文字识别的各个方面,具体领域入下。
  • cocacola456
  • cocacola456
  • 2017-10-25 11:49
  • 83

正则表达式+精准高效正则(终极篇)

如果纯粹是为了挑战自己的正则水平,用来实现一些特效(例如使用正则表达式计算质数、解线性方程),效率不是问题;如果所写的正则表达式只是为了满足一两次、几十次的运行,优化与否区别也不太大。但是,如果所写的...
  • s_jobs
  • s_jobs
  • 2012-10-26 10:45
  • 1799
    个人资料
    • 访问:155305次
    • 积分:1639
    • 等级:
    • 排名:千里之外
    • 原创:57篇
    • 转载:2篇
    • 译文:0篇
    • 评论:29条
    文章分类
    最新评论