运用DFA算法加密。

首先我先对敏感词库初始化,若我的敏感词库为

冰毒
白粉
大麻
大坏蛋

初始化之后得到的是下面这样。:

{冰={毒={isEnd=1}, isEnd=0}, 白={粉={isEnd=1}, isEnd=0}, 大={麻={isEnd=1}, isEnd=0, 坏={蛋={isEnd=1}, isEnd=0}}}。

ok,我把初始化之后的数据用A来表示。假设待检测的文字为:张三是个大坏蛋,他竟然吸食白粉和冰毒。

后面检测文字中是否有敏感词的时候,先把要检测的文字迭代循环,并转换成charAt值,这样的话,

如果 A.get(charAt) 为空的话,说明这个字不在敏感词库中,比如 "张","三","是","个" ........

如果 A.get(charAt) 不为空的话,说明这个字存在敏感词库中,比如 "大","坏","蛋" ...........

假设我们检测到  "大" "坏" 的时候,发现这个字存在于敏感词库中,这个时候需要看项目需求,如果只是检测 输入框内是否含有敏感词,

那这里就可以不进行判断了,已经含有敏感词了。

如果要把所有的敏感词用 "*" 号替换的话,那就要继续往下匹配,判断该敏感词是否是最后一个......

以上就是基本思路了,下面上代码 ,不懂的可以留言给我。。。

温馨提示:

初始化敏感词库的时候

1、加了redis缓存

2、敏感词库我是放在了服务器下面

3、编码格式注意,代码里的编码格式要与你的敏感词库的编码格式一致。utf-8或者gbk。(win下把txt另存为可以看到,linux下vim txt,:set fileencoding)

linux下文件编码格式转换,这里是gbk -> utf-8:iconv -f gb18030 -t utf-8 sensitiveword.txt -o sensitiveword.txt

你们用main方法测试的时候,要把缓存注释掉,敏感词库路径改为 你们本地。

package com.cmcc.admin.common.sensitive;import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;/*** @Type SensitiveWordFilter.java*/
public class SensitiveWordFilter {@SuppressWarnings("rawtypes")private Map sensitiveWordMap = null;public static int minMatchType = 1; //最小匹配规则public static int maxMatchType = 2; //最大匹配规则/*** 构造函数,初始化敏感词库* @throws Exception* @since 1.8* @author whb*/public SensitiveWordFilter() throws Exception {sensitiveWordMap = new SensitiveWordInit().initKeyWord();}/*** 检查文字中敏感词的长度* @param txt* @param beginIndex* @param matchType* @return 如果存在,则返回敏感词字符的长度,不存在返回0* @since 1.8* @author whb*/@SuppressWarnings("rawtypes")public int checkSensitiveWord(String txt, int beginIndex, int matchType) {Map nowMap = sensitiveWordMap;boolean flag = false; //敏感词结束标识位:用于敏感词只有1位的情况char word = 0;int matchFlag = 0; //匹配标识数默认为0for (int i = beginIndex; i < txt.length(); i++) {word = txt.charAt(i);nowMap = (Map) nowMap.get(word); //获取指定keyif (nowMap == null) {break;//不存在,直接返回}//输入的字(排列组合的匹配)出现在敏感词库中,判断是否为最后一个matchFlag++; //找到相应key,匹配标识+1if (isEnd(nowMap)) { //如果为最后一个匹配规则,结束循环,返回匹配标识数flag = true; //结束标志位为trueif (SensitiveWordFilter.minMatchType == matchType) {break;//最小规则,直接返回,最大规则还需继续查找}}}if (matchFlag < 2 || !flag) { //长度必须大于等于1,为词matchFlag = 0;}return matchFlag;}/*** 是否包含敏感词* @param txt* @param matchType* @return true:是;false:否* @since 1.8* @author whb*/public boolean isContaintSensitiveWord(String txt, int matchType) {boolean flag = false;for (int i = 0; i < txt.length(); i++) {int matchFlag = this.checkSensitiveWord(txt, i, matchType);if (matchFlag > 0) {flag = true;}}return flag;}/*** 是否包含敏感词(重庆项目默认值,按最小匹配规则来,只要有敏感词就ok)* 如果敏感词库为:*          中*          中国*          中国人*  初始化之后为:{中={isEnd=1, 国={人={isEnd=1}, isEnd=1}}}*  测试的文字为:我是一名中国人。*  1、按最小规则匹配,  匹配 中 的时候,就为最后一个了 直接break。*  2、按最大规则匹配,  匹配 中 的时候,就为最后一个,继续匹配 国,人。* @param txt* @return true:是;false:否* @since 1.8* @author whb*/public boolean isSensitive(String txt) {boolean flag = false;for (int i = 0; i < txt.length(); i++) {int matchFlag = this.checkSensitiveWord(txt, i, 1);if (matchFlag > 0) {flag = true;}}return flag;}/*** 获取文字中的敏感词* @param txt* @param matchType* @return* @since 1.8* @author whb*/public Set<String> getSensitiveWord(String txt, int matchType) {Set<String> sensitiveWordList = new HashSet<String>();for (int i = 0; i < txt.length(); i++) {int length = checkSensitiveWord(txt, i, matchType);if (length > 0) { //存在,加入list中sensitiveWordList.add(txt.substring(i, i + length));i = i + length - 1; //减1的原因,是因为for会自增}}return sensitiveWordList;}/*** 替换敏感字字符* @param txt* @param matchType* @param replaceChar* @return* @since 1.8* @author whb*/public String replaceSensitiveWord(String txt, int matchType, String replaceChar) {String resultTxt = txt;Set<String> set = this.getSensitiveWord(txt, matchType); //获取所有的敏感词Iterator<String> iterator = set.iterator();String word = null;String replaceString = null;while (iterator.hasNext()) {word = iterator.next();replaceString = getReplaceChars(replaceChar, word.length());resultTxt = resultTxt.replaceAll(word, replaceString);}return resultTxt;}/*** 获取替换字符串* @param replaceChar* @param length* @return* @since 1.8* @author whb*/private String getReplaceChars(String replaceChar, int length) {String resultReplace = replaceChar;for (int i = 1; i < length; i++) {resultReplace += replaceChar;}return resultReplace;}/*** 判断是否为最后一个* @param nowMap* @return* @since 1.8* @author whb*/@SuppressWarnings("rawtypes")private boolean isEnd(Map nowMap) {boolean flag = false;if ("1".equals(nowMap.get("isEnd"))) {flag = true;}return flag;}public static void main(String[] args) throws Exception {SensitiveWordFilter filter = new SensitiveWordFilter();System.out.println("敏感词的数量:" + filter.sensitiveWordMap.size());String string = "王弘博是个大坏蛋,他竟然吸食白粉和冰毒";System.out.println("待检测语句的字数:" + string.length());long beginTime = System.currentTimeMillis();Set<String> set = filter.getSensitiveWord(string, 1);String result = filter.replaceSensitiveWord(string, 1, "*");boolean flag = filter.isSensitive(string);System.out.println(flag);long endTime = System.currentTimeMillis();System.out.println("语句中包含敏感词的个数为:" + set.size() + "。包含:" + set);System.out.println("敏感词处理之后为:"+result);System.out.println("总共消耗时间为:" + (endTime - beginTime));}
}

SensitiveWordInit 初始化代码如下:

package com.cmcc.admin.common.sensitive;import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import com.cmcc.aqb.cache.redis.RedisClient;/*** @Type SensitiveWordInit.java* @Desc* @author whb* @date 2017年8月23日 下午1:57:03* @version*/
public class SensitiveWordInit {private static final String ENCODING = "utf-8"; //字符编码@SuppressWarnings("rawtypes")public HashMap sensitiveWordMap;public SensitiveWordInit() {super();}static RedisClient redisClient = null;private static String SPILIT = "#";private static int EXPIRE_TIME = 3600;// secondsprivate static String SENSITIVE_WORD = SensitiveWordInit.class.getName();private String sensitiveWordKey(String type) {StringBuilder sb = new StringBuilder();sb.append(type).append(SPILIT).append("sensitiveWordInit");return sb.toString();}/**** @return* @throws Exception* @since 1.8* @author whb*/@SuppressWarnings({ "rawtypes", "resource" })public Map initKeyWord() {try {ApplicationContext ac = new ClassPathXmlApplicationContext(new String[] {"spring/datasource.xml", "spring/cache.xml" });redisClient = (RedisClient) ac.getBean("redisClient");String key = sensitiveWordKey(SENSITIVE_WORD);sensitiveWordMap = redisClient.get(key);if (sensitiveWordMap == null) {Set<String> set = readSensitiveWordFile();addSensitiveWordToHashMap(set);redisClient.put(key, sensitiveWordMap, EXPIRE_TIME);}((AbstractApplicationContext) ac).registerShutdownHook();return sensitiveWordMap;} catch (Exception e) {throw new RuntimeException("初始化敏感词库错误");}}/*** 读取敏感词库,并把内容放到set里* @return* @throws Exception* @since 1.8* @author whb*/private Set<String> readSensitiveWordFile() throws Exception {Set<String> set = null;File file = new File("/home/sensitiveword.txt");try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), ENCODING))) {if (file.isFile() && file.exists()) {set = new HashSet<String>();String txt = null;while ((txt = bufferedReader.readLine()) != null) {set.add(txt);}} else {throw new Exception("敏感词库文件不存在");}} catch (Exception e) {e.printStackTrace();throw e;}return set;}/*** 读取敏感词库,将敏感词放入HashSet中,构建一个DFA算法模型:<br>* 中 = {*      isEnd = 0*      国 = {<br>*           isEnd = 1*           人 = {isEnd = 0*                民 = {isEnd = 1}*                }*           男  = {*                  isEnd = 0*                   人 = {*                        isEnd = 1*                       }*               }*           }*      }*  五 = {*      isEnd = 0*      星 = {*          isEnd = 0*          红 = {*              isEnd = 0*              旗 = {*                   isEnd = 1*                  }*              }*          }*      }* @param keyWordSet* @since 1.8* @author whb*/@SuppressWarnings({ "rawtypes", "unchecked" })private void addSensitiveWordToHashMap(Set<String> keyWordSet) {sensitiveWordMap = new HashMap(keyWordSet.size()); //初始化敏感词容器,避免扩容操作String key = null;Map nowMap = null;Map<String, String> newWorMap = null;Iterator<String> iterator = keyWordSet.iterator();while (iterator.hasNext()) {key = iterator.next();nowMap = sensitiveWordMap;for (int i = 0; i < key.length(); i++) {char charKey = key.charAt(i); //转换成char型Object wordMap = nowMap.get(charKey);if (wordMap != null) {nowMap = (Map) wordMap; //一个一个放进Map中} else { //不存在,则构建一个Map,同时将isEnd设置为0,因为它不是最后一个newWorMap = new HashMap<String, String>();newWorMap.put("isEnd", "0");//不是最后一个nowMap.put(charKey, newWorMap);//没有这个key,就把(isEnd,0) 放在Map中nowMap = newWorMap;}if (i == key.length() - 1) { //最后一个nowMap.put("isEnd", "1");}}}}}

DFA敏感词过滤算法相关推荐

  1. 敏感词过滤算法 为内容保驾护航 Java/.Net/C++/c/Python等语言是如何进行敏感词打码限制的 高效防范违规内容

    有人的地方,就有江湖,有输入框的地方,就有注入风险!有输入框的地方,就有敏感词!敏感词就像一个平台杀手,可能直接导致平台被封锁! 敏感词是一个APP.一个网站.一个内容平台的"杀手" ...

  2. trie树之敏感词过滤算法

    之前写过一篇关于Trie树的介绍:Trie树--在一个字符串集合中快速查找某个字符串.今天就用Trie树来实现敏感词过滤算法. 首先简单介绍一下Trie树的数据结构: 1.根节点不存储字符. 2.Tr ...

  3. 【C++】实现敏感词过滤算法(含源码)

    敏感词过滤算法(聚合词树查询法) 1.构建词树 2.敏感词判断 3.遍历文本 关于敏感词过滤算法,数不胜数,在参考众多算法后,选取了比较实用的算法,进行总结与改进.大家可以参考一下链接: 敏感词过滤算 ...

  4. 浅析过滤敏感词过滤算法(C++)

    本文转自浅析敏感词过滤算法(C++),自己也在其基础上根据自己的情况做了一点修改. 为了提高查找效率,这里将敏感词用树形结构存储,每个节点有一个map成员,其映射关系为一个string对应一个Word ...

  5. 算法-DFA算法-敏感词过滤算法(OC、Swift、Python)

    前言 前段时间,公司的IM SDK想做敏感词过滤,但是后端的小伙伴<比较忙>,在开产品需求会的时候想把敏感词过滤放到前端,让iOS.安卓自己搞,但是前端小伙伴写了一个方法来检测一段文本,耗 ...

  6. 记录一次敏感词过滤算法DFA的应用案例

    目录 0. DFA是什么? 1.为什么要用DFA 2.DFA工具类实现 3.性能对比效果 3.1 普通关键字过滤 3.2 DFA关键字过滤 0. DFA是什么? 参考文档:敏感词过滤的算法原理之DFA ...

  7. java实现敏感词过滤算法DFA并忽略敏感词中的特殊字符

    参考文章:https://blog.csdn.net/chenssy/article/details/26961957 补充说明: 1.具体的DFA介绍参考原文章,此处只是补充了文章中没有介绍的点以及 ...

  8. 字符串匹配算法 -- AC自动机 基于Trie树的高效的敏感词过滤算法

    文章目录 1. 算法背景 2. AC自动机实现原理 2.1 构建失败指针 2.2 依赖失败指针过滤敏感词 3. 复杂度及完整代码 1. 算法背景 之前介绍过单模式串匹配的高效算法:BM和KMP 以及 ...

  9. 【python 走进NLP】英文敏感词过滤算法改进版本

    中文DFA算法过滤敏感词改进版本 # 中文DFA算法过滤敏感词改进版本 class Chinese_DFAFilter():def __init__(self):self.keyword_chains ...

  10. 敏感词过滤算法:前缀树算法

    背景 平时我们在逛贴吧的时候,我们经常可以看到一些形如 "***"的符号,通过上下文,我们也可以很容易猜到这些词原来是骂人的话,只是被系统和谐了.那么这是如何实现的呢?作为普通人, ...

最新文章

  1. 06 回归算法 - 损失函数、过拟合欠拟合
  2. windows hider
  3. oracle 年龄计算 岁 月 天
  4. 关于zendframework中的Zend_Db_Expr(不自动加引号)
  5. 在eclipse中输入.后提示解决
  6. android新闻app_如何利用 Python 爬虫实现给微信群发新闻早报?
  7. hangfire 过期记录_韩剧丨顶楼、空洞、再次十八岁、僵尸侦探、青春记录
  8. 不再颓废,重新开始,牛客第一题1016. 部分A+B (15)
  9. U盘快速​安装Ubuntu系统
  10. 【Linux安全】安全口令策略设置
  11. linux的for循环怎么写,Linux命令:for循环写法总结
  12. 【ZOJ - 3329】One Person Game(带循环的概率dp,数学期望,高斯消元,数学)
  13. Tensorflow深度学习应用(进阶篇)-1
  14. C#.Net 中的 new 的几个用法
  15. UGUI 在面板经常使用的表格布局制作
  16. windows核心编程之用户模式下的线程同步
  17. 网页中设定表格边框的厚度的属性_补充一点前端知识
  18. 十步会用IOCOMP–iplotx控件
  19. Elasticsearch的搜索命令
  20. 错误代码: SEC_ERROR_REUSED_ISSUER_AND_SERIAL(解决办法)

热门文章

  1. webview加载百度失败_独家|神秘SDK暗刷百度广告 植入数千款APP
  2. 移动应用商店比较分析
  3. MPQ4573:和“讨厌”的二极管说拜拜
  4. 【结课报告】游戏中的知识产权
  5. 雅虎前端性能优化的35条军规
  6. 2013 前瞻 + 技术牛
  7. GBK字符串转Unicode字符串
  8. Python打码API(学习使用)
  9. 2021SC@SDUSC Zxing开源代码(十五)PDF417二维码(一)
  10. sap abap开发从入门到精通_SAP开发-ABAP数据字典(搜索帮助增强)