1. 程式人生 > >Java Web敏感詞過濾演算法

Java Web敏感詞過濾演算法

1.DFA演算法

DFA演算法的原理可以參考 這裡 ,簡單來說就是通過Map構造出一顆敏感詞樹,樹的每一條由根節點到葉子節點的路徑構成一個敏感詞,例如下圖:

程式碼簡單實現如下:

public class TextFilterUtil {
  //日誌
  private static final Logger LOG = LoggerFactory.getLogger(TextFilterUtil.class);
  //敏感詞庫
  private static HashMap sensitiveWordMap = null;
  //預設編碼格式
  private static final String ENCODING = "gbk";
  //敏感詞庫的路徑
  private static final InputStream in = TextFilterUtil.class.getClassLoader().getResourceAsStream("sensitive/keyWords.txt");
  /**
   * 初始化敏感詞庫
   */
  private static void init() {
    //讀取檔案
    Set<String> keyWords = readSensitiveWords();
    //建立敏感詞庫
    sensitiveWordMap = new HashMap<>(keyWords.size());
    for (String keyWord : keyWords) {
      createKeyWord(keyWord);
    }
  }
  /**
   * 構建敏感詞庫
   *
   * @param keyWord
   */
  private static void createKeyWord(String keyWord) {
    if (sensitiveWordMap == null) {
      LOG.error("sensitiveWordMap 未初始化!");
      return;
    }
    Map nowMap = sensitiveWordMap;
    for (Character c : keyWord.toCharArray()) {
      Object obj = nowMap.get(c);
      if (obj == null) {
        Map<String, Object> childMap = new HashMap<>();
        childMap.put("isEnd", "false");
        nowMap.put(c, childMap);
        nowMap = childMap;
      } else {
        nowMap = (Map) obj;
      }
    }
    nowMap.put("isEnd", "true");
  }
  /**
   * 讀取敏感詞檔案
   *
   * @return
   */
  private static Set<String> readSensitiveWords() {
    Set<String> keyWords = new HashSet<>();
    BufferedReader reader = null;
    try {
      reader = new BufferedReader(new InputStreamReader(in, ENCODING));
      String line;
      while ((line = reader.readLine()) != null) {
        keyWords.add(line.trim());
      }
    } catch (UnsupportedEncodingException e) {
      LOG.error("敏感詞庫檔案轉碼失敗!");
    } catch (FileNotFoundException e) {
      LOG.error("敏感詞庫檔案不存在!");
    } catch (IOException e) {
      LOG.error("敏感詞庫檔案讀取失敗!");
    } finally {
      if (reader != null) {
        try {
          reader.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
        reader = null;
      }
    }
    return keyWords;
  }
  /**
   * 檢查敏感詞
   *
   * @return
   */
  private static List<String> checkSensitiveWord(String text) {
    if (sensitiveWordMap == null) {
      init();
    }
    List<String> sensitiveWords = new ArrayList<>();
    Map nowMap = sensitiveWordMap;
    for (int i = 0; i < text.length(); i++) {
      Character word = text.charAt(i);
      Object obj = nowMap.get(word);
      if (obj == null) {
        continue;
      }
      int j = i + 1;
      Map childMap = (Map) obj;
      while (j < text.length()) {
        if ("true".equals(childMap.get("isEnd"))) {
          sensitiveWords.add(text.substring(i, j));
        }
        obj = childMap.get(text.charAt(j));
        if (obj != null) {
          childMap = (Map) obj;
        } else {
          break;
        }
        j++;
      }
    }
    return sensitiveWords;
  }
}

2.TTMP演算法

TTMP演算法由網友原創,關於它的起源可以檢視 這裡 ,TTMP演算法的原理是將敏感詞拆分成“髒字”的序列,只有待比對字串完全由“髒字”組成時,才去判斷它是否為敏感詞,減少了比對次數。這個演算法的簡單實現如下:

public class TextFilterUtil {
  //日誌
  private static final Logger LOG = LoggerFactory.getLogger(TextFilterUtil.class);
  //預設編碼格式
  private static final String ENCODING = "gbk";
  //敏感詞庫的路徑
  private static final InputStream in = TextFilterUtil.class.getClassLoader().getResourceAsStream("sensitive/keyWords.txt");
  //髒字庫
  private static Set<Character> sensitiveCharSet = null;
  //敏感詞庫
  private static Set<String> sensitiveWordSet = null;
  /**
   * 初始化敏感詞庫
   */
  private static void init() {
    //初始化容器
    sensitiveCharSet = new HashSet<>();
    sensitiveWordSet = new HashSet<>();
    //讀取檔案 建立敏感詞庫
    readSensitiveWords();
  }
  /**
   * 讀取本地的敏感詞檔案
   *
   * @return
   */
  private static void readSensitiveWords() {
    BufferedReader reader = null;
    try {
      reader = new BufferedReader(new InputStreamReader(in, ENCODING));
      String line;
      while ((line = reader.readLine()) != null) {
        String word = line.trim();
        sensitiveWordSet.add(word);
        for (Character c : word.toCharArray()) {
          sensitiveCharSet.add(c);
        }
      }
    } catch (UnsupportedEncodingException e) {
      LOG.error("敏感詞庫檔案轉碼失敗!");
    } catch (FileNotFoundException e) {
      LOG.error("敏感詞庫檔案不存在!");
    } catch (IOException e) {
      LOG.error("敏感詞庫檔案讀取失敗!");
    } finally {
      if (reader != null) {
        try {
          reader.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
        reader = null;
      }
    }
    return;
  }
  /**
   * 檢查敏感詞
   *
   * @return
   */
  private static List<String> checkSensitiveWord(String text) {
    if (sensitiveWordSet == null || sensitiveCharSet == null) {
      init();
    }
    List<String> sensitiveWords = new ArrayList<>();
    for (int i = 0; i < text.length(); i++) {
      Character word = text.charAt(i);
      if (!sensitiveCharSet.contains(word)) {
        continue;
      }
      int j = i;
      while (j < text.length()) {
        if (!sensitiveCharSet.contains(word)) {
          break;
        }
        String key = text.substring(i, j + 1);
        if (sensitiveWordSet.contains(key)) {
          sensitiveWords.add(key);
        }
        j++;
      }
    }
    return sensitiveWords;
  }
}

注:以上程式碼實現僅用於展示思路,在實際使用中還有很多地方可以優化。

個人技術分享微信公眾號,歡迎關注一起交流。

相關推薦

Java Web敏感過濾演算法

1.DFA演算法DFA演算法的原理可以參考 這裡 ,簡單來說就是通過Map構造出一顆敏感詞樹,樹的每一條由根節點到葉子節點的路徑構成一個敏感詞,例如下圖:程式碼簡單實現如下:public class TextFilterUtil { //日誌 private stat

敏感過濾演算法:字首樹演算法

背景 平時我們在逛貼吧、牛客網的時候,我們經常可以看到一些形如 “***”的符號,通過上下文,我們也可以很容易猜到這些詞原來是罵人的話,只是被系統和諧了。那麼這是如何實現的呢?作為普通人,我們最先想到的一種辦法就是把所有敏感串存入一個列表中,然後使用者每發一條內容後臺就把該內容與敏感串列表

【python 走進NLP】英文敏感過濾演算法改進版本

中文DFA演算法過濾敏感詞改進版本 # 中文DFA演算法過濾敏感詞改進版本 class Chinese_DFAFilter(): def __init__(self): self.keyword_chains = {} s

C#敏感過濾演算法實現

1.DFA演算法簡介DFA全稱為:Deterministic Finite Automaton,即確定有窮自動機。其特徵為:有一個有限狀態集合和一些從一個狀態通向另一個狀態的邊,每條邊上標記有一個符號,其中一個狀態是初態,某些狀態是終態。但不同於不確定的有限自動機,DFA中不

DFA敏感過濾演算法

運用DFA演算法加密。首先我先對敏感詞庫初始化,若我的敏感詞庫為冰毒白粉大麻大壞蛋初始化之後得到的是下面這樣。:{冰={毒={isEnd=1}, isEnd=0}, 白={粉={isEnd=1}, isEnd=0}, 大={麻={isEnd=1}, isEnd=0, 壞={蛋

高效能的敏感過濾演算法 可以忽略大小寫、全半形、簡繁體、特殊符號干擾 (二)

/// <summary> /// 敏感詞過濾 已忽略大小寫 全半形 簡繁體差異 特殊符號 html標籤 干擾 /// </summary> public static class FilterKeyWords { priv

java DFA 敏感過濾

@SuppressWarnings("unchecked") public class SensitiveWordUtils { /** * 只要匹配到一個就返回 */ public static final int

DFA演算法實現Java敏感過濾

      敏感詞、文字過濾是一個網站必不可少的功能,如何設計一個好的、高效的過濾演算法是非常有必要的。前段時間我一個朋友(馬上畢業,接觸程式設計不久)要我幫他看一個文字過濾的東西,它說檢索效率非常慢。我把它程式拿過來一看,整個過程如下:讀取敏感詞庫、如果Ha

java敏感過濾(庫+演算法)高效率驗證

需求:使用者輸入一段文字,驗證是否包含敏感詞,以及具體的是哪些敏感詞,替換為*等....1.需要一個詞庫,我這裡就是一個從github下載的一個txt檔案。已轉存到百度網盤,點選下載詞庫,提取碼:tk3g2.DFA演算法,效能卓越,請放心使用,直接上java程式碼:packa

Java利用DFA演算法實現敏感過濾

前言: 敏感詞文字過濾是一個網站必不可少的功能,如何設計一個好的、高效的過濾演算法是非常有必要的。作為一般開發人員來說首先考慮的肯定是簡單的匹配,這樣是可以實現功能,但效率比較慢,在高階一點的就是正則表示式,比前一個好一點,但終究還是一丘之貉,非常遺憾,兩種方法都不可取。當

Java 敏感過濾Java 敏感替換,Java 敏感工具類

blog rds log code ima 方法 www enter iteye Java 敏感詞過濾,Java 敏感詞替換,Java 敏感詞工具類 =========================== ?Copyright 蕃薯耀 2017年9月25日 http:

java HashMap實現中文分器 應用:敏感過濾實現

今天下午部門內部技術分享是分詞器演算法。這次的主講是大名鼎鼎的Ansj分詞器的作者-孫健。 作者簡介: Ansj分詞器作者 elasticsearch-sql(elasticsearch的sql外掛)作者,支援sql查詢 nlp-lang自然語言工具包發起人 NLPCN(自然語言處理

JAVA 敏感過濾

package me.mymilkbottles; import org.apache.commons.lang.CharUtils; import java.io.File; import java.util.HashMap; import java.ut

DFA演算法實現敏感過濾

DFA,即Deterministic Finite Automaton,也就是確定有窮自動機。比如我們有愛戀、哈哈、感動、靜靜、發呆、太多、啦啦這幾個敏感詞,以上其實是通過HashMap組織成的樹形結構,比如我們通過“太”就可以知道這個字是否是“太多”這個詞的最後一個字,並且

敏感過濾演算法原理之DFA演算法

轉載自:https://blog.csdn.net/chenssy/article/details/26961957敏感詞、文字過濾是一個網站必不可少的功能,如何設計一個好的、高效的過濾演算法是非常有必要的。前段時間我一個朋友(馬上畢業,接觸程式設計不久)要我幫他看一個文字過

61 dfa 實現敏感過濾

引用 nbsp bsp 概念 pre clas logs code println 基本的概念 Class class=null 【只是在棧內存中有了指向,堆內存並沒有分配內存】 Class class=new Class()【棧內存中有了指向(引用),堆內存也分配了內存

PHP實現敏感過濾系統

trie樹 sel 重復 .html ole lang 最大 foreach header PHP實現敏感詞過濾系統 安裝說明 安裝PHP擴展 trie_filter,安裝教程 http://blog.41ms.com/post/39.html 安

5分鐘Serverless實踐 | 構建無服務器的敏感過濾後端系統

trab 平臺 ase lac mps creat base pen 服務器架構 前言 在上一篇“5分鐘Serverless實踐”系列文章中,我們介紹了什麽是Serverless,以及如何構建一個無服務器的圖片鑒黃Web應用,本文將延續這個話題,以敏感詞過濾為例,介紹如何構

JavaScript 版敏感過濾

    考慮到太多的違禁詞彙,所以縮小化顯示,縮小到讓你看不清楚。如果想看清楚一點,還是去演示地址裡面看吧。消滅敏感詞是每個公民義不容辭的責任!你不站崗我不站崗,誰保衛咱祖國誰來保衛家!讀者們你們要是敢舉報,看我不砍死你! 安裝方法 # 安裝到當前專案 np

敏感過濾工具

SensitivewordEngine.java 敏感詞過濾工具類 package keyFilter; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.uti