IM项目需要对上边传输的消息进行必要的过滤。如果总是对着某人输入f**k就显得不太文明了。

一个通用且简单的做法是,设定一批敏感词,如果消息中出现这些词,由系统进行必要的处理。怎么实现这个功能呢?

一、能够实现敏感词过滤功能的方法有很多

方法有很多,我简单罗列了几个。

1、直接将敏感词组织成String后,利用indexOf方法来查询。

2、传统的敏感词入库后SQL查询。

3、利用Lucene建立分词索引来查询。

4、利用DFA算法来进行。

显然,方法1和方法2在性能上基本无法满足IM系统高效处理消息的需求,放弃。

方法3,采用Lucene建立本地分词索引,将消息内容分词后,在索引库里搜索。这个方法较复杂,且分词效率也不会很高,放弃。

大多数的敏感词过滤系统采用的是方法4,DFA算法。

二、DFA简介

DFA是什么?这里有必要简单介绍一下这个概念(这部分看不懂没关系,可以跳过)。

1、DFA定义

DFA翻译成中文是“确定有穷自动机 ”

定义:一个确定有穷自动机(DFA)M是一个五元组:M=(K,Σ,f,S,Z)其中

① K是一个有穷集,它的每个元素称为一个状态;

② Σ是一个有穷字母表,它的每个元素称为一个输入符号,所以也称Σ为输入符号字母表;

③ f是转换函数,是K×Σ→K上的映射(且可以是部分函数),即,如 f(ki,a)=kj,(ki∈K,kj∈K)就意味着,当前状态为ki,输入符为a时,将转换为下一个状态kj,我们把kj称作ki的一个后继状态;

④ S ∈ K是唯一的一个初态;

⑤ Z⊂K是一个终态集,终态也称可接受状态或结束状态。

2、DFA例子

3、DFA状态图表示

假定DFA M含有m个状态,n个输入字符,那么这个状态图含有m个节点,每个节点最多有n个弧射出,整个图含有唯一一个初态点和若干个终态点,初态节点冠以双箭头“=>”,终态节点用双圈表示,若f(ki ,a)=kj,则从状态结点ki到状态节点kj画标记为a的弧。

4、DFA所接受

对于Σ* 中的任何符号串t,若存在一条从初态到某一终态的道路,且这条道路上所有弧的标记连接成的字符串等于t,则称t可为DFA M所接受,若M的初态同时又是终态,则空字可为M所识别(接受)。

即:若 t∈ Σ* , f(S, t)=P, 其中S为M的开始状态,P∈Z,Z为 终态集。

则称 t 为 DFA M所接受(识别)。

如果看懂了DFA的介绍,我们可以这么理解敏感词过滤系统。用需要被过滤的敏感词构建一个DFA(确定有穷自动机 ),然后遍历需要过滤的文本,判断文本中是否有DFA可接受(识别)的字符串即可。

如果没有看懂DFA,看下边一节也OK。

三、用Trie树构建DFA

Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。

假设有b,abc,abd,bcd,abcd,efg,hii 这7个单词(实际使用中,这些单词就是敏感词),我们构建的树如下图

如上图所示,对于每一个节点,从根遍历到他的过程就是一个单词,如果这个节点被标记为红色,就表示这个单词存在,否则不存在。

过滤敏感词,就是把需要过滤的文本,从第一个字开始,逐个字往后在Trie树中查找。如果能走到树的结束节点,则就能发现敏感词!

四、防止回溯

1、回溯的场景

看一句话待过滤的文本(以下简称母串)“瓜子二手车成交量全国领先”,再看下图模拟的几个敏感词。我们来看看检索过程。

(1)第1个字“瓜”在Trie树的第一层节点(第一层节点有“二”、“瓜”、“西”三个字);继续(在中间的子树)往后找“子”字,在树枝的后续节点;继续找“二”,继续找“手”,继续找“车”,"车"字无法找到,查找失败。

(2)(这里不能从“二”字开始找,需要回溯到“子”字,万一有“子”字开始的敏感词呢 )第2个字“子”不在Trie树第一层节点,查找失败。

(3)第3个字“二”字,在Trie树第一层节点……

(4)后续文字按此方法逐字往后查找即可。

这个查找方法能够求解,但是效率不高(注意第2步),我们读到了后边的文字,但是由于没有命中,检索发生了回退,导致效率下降。事实上,我们在第1步已经比较过“二手”这个词,如果能利用第1步中比较的结果,直观感觉是能够加快匹配出“二手车”这个敏感词的。

2、前缀指针

前面的场景很像字符串查找的KMP算法,KMP算法可以防止字符串查找过程中的指针回溯。那Trie树的结构有没有办法也避免这种情况发生呢?

答案是肯定的。参考KMP算法(百度一下你就知道了) 的最长相同前后缀的方法,来避免回溯。

这里首先需要理解“前缀”、“后缀”的思想。如果不了解这两个概念,推荐一篇KMP算法讲得特别清楚的博文http://www.cnblogs.com/c-cloud/p/3224788.html(一定要读)。

为了避免回溯,参考KMP的next数组,在Trie图中定义“前缀指针 ”

“前缀指针 ”定义:从根节点到节点P可以得到一个字符串S,节点P的前缀指针定义为 指向树中出现过的S的最长后缀(不能等于S)

后续文章将详细讲解怎么高效构建“前缀指针 ”,如何快速遍历母串,以及工程上如何实现的问题。

怎么设计高效的敏感词过滤系统(一)相关推荐

  1. PHP实现敏感词过滤系统

    PHP实现敏感词过滤系统 安装说明 安装PHP扩展 trie_filter,安装教程 http://blog.41ms.com/post/39.html 安装PHP扩展 swoole,安装教程 htt ...

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

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

  3. 一个高效的敏感词过滤方法(PHP)

    效率对比(12688个字符,替换1次): str_replace: 0.109937906265秒 strtr: 0.0306839942932秒 替换结果对比 比如:「张三」.「张三丰」.「张三丰田 ...

  4. PHP高效的敏感词过滤方法

    <?php // 测试文件demo.php $badword = array('张三','张三丰','张三丰田' ); // array_combine() 函数通过合并两个数组来创建一个新数组 ...

  5. 5分钟Serverless实践 | 构建无服务器的敏感词过滤后端系统

    前言 在上一篇"5分钟Serverless实践"系列文章中,我们介绍了什么是Serverless,以及如何构建一个无服务器的图片鉴黄Web应用,本文将延续这个话题,以敏感词过滤为例 ...

  6. PHP敏感词过滤【整理实践版】

    2019独角兽企业重金招聘Python工程师标准>>> 由于国内互联网管制政策,强大的敏感词过滤系统成为了每一个网站必须具备的基本功能,尤其是那些涉及UGC内容的站点. 对敏感词过滤 ...

  7. 5分钟搞定敏感词过滤!

    函数工作流(FunctionGraph,FGS)是一项基于事件驱动的函数托管计算服务,托管函数具备以毫秒级弹性伸缩.免运维.高可靠的方式运行.通过函数工作流,开发者无需配置和管理服务器,只需关注业务逻 ...

  8. 游戏敏感词过滤的常见方式记录

    敏感词过滤是随着互联网社区发展,一种阻止网络犯罪和网络暴力的技术手段.通过对可能存在犯罪或网络暴力,对可能的关键词进行有针对性的筛查和屏蔽. 很多时候我们能够防患于未然,把后果严重的犯罪行为扼杀于萌芽 ...

  9. 游戏里敏感词过滤的常见方式有哪些

    随着互联网的发展,"敏感词过滤"这一需求也在市场中不断增加. 敏感词过滤是一种阻止网络不良信息扩散和灰黑产扩张的技术手段,对可能存在不合规的关键词进行有针对性的筛查和屏蔽.通过这样 ...

最新文章

  1. mysql拷贝恢复.frm_通过.frm .ibd文件恢复MySQL数据
  2. 排错-Loadrunner录制打不开浏览器解决方法
  3. hdu4848 DFS 暴搜+ 强剪枝
  4. python开始之路—基础中的基础
  5. 高质量壁纸网站,满足壁纸控的所有想象!
  6. ActiveMq工作笔记002---Centos7.3安装ActiveMq
  7. 解决font-weight:600在安卓机不生效的方法
  8. Codeforces Round #698 (Div. 2) (思维)
  9. List的Sort自定义排序实例
  10. 2010年04月 小记(MVC2validation, svn)
  11. 一元、二元、三元逻辑运算符
  12. 互联网专用计算机屏保,18个Windows 98屏保,简直怀念!
  13. 如何批量修改文件夹名称中的某个字?
  14. DevOps开发运维:Buddy中文版正式发布
  15. http返回码301、302、307、305含义和区别
  16. Python编程快速上手让繁琐工作自动化中文高清完整版PDF带书签
  17. 教育行业电商SaaS系统解决方案:助力企业实现经营、管理一体化
  18. 多个域名指向同一个网站实现方法
  19. 【券后价9.90元】【包邮】荷叶茶冬瓜荷叶茶叶纯干玫瑰花茶袋泡花草茶包组合天然决明正品子...
  20. linux中kvm配置文件,如何在linux中通过kvm安装虚拟机

热门文章

  1. 面试项目经理,这12个问题一定会被问到(建议收藏)
  2. Redis启动多端口、运行多实例
  3. 记一次完整手机APP项目的开发
  4. ML之VC维:VC维(Vapnik-Chervonenkis Dimension)理论的概述(衡量模型复杂度和预测能力的指标)的简介、案例理解之详细攻略
  5. 用FE-固定效应模型能做因果推断吗?
  6. 毛星云opencv之SHi-Tomasi角点检测综合程序
  7. 基于javaweb的私人牙科诊所病历管理系统(java+jsp+css+javascript+mysql)
  8. Linux上编译curl
  9. java52-抽象类
  10. Python基础(类与对象)