最近在做遊戲的聊天功能,需要在客戶端接入敏感詞過濾,較低成本的實現方法有字典匹配和正規表示式匹配,但效率上較低。大致 google 了一遍,發現dfa
演算法是實現敏感詞過濾效率較高的選擇,下面是具體實現過程。
dfa
演算法,即deterministic finite automaton
,中文翻譯是有窮自動機。它是通過 event 和當前 state 得到下乙個 state 的,即event + curstate = nextstate。此演算法沒有複雜的計算,基本上都是控制狀態的轉移。
本質上這裡主要是構建好髒詞樹即完成了大部分的工作,檢測過程其實很簡單,這裡需要建立乙個樹結構體:
// 敏感詞樹結構
class wordnode
public getchild(name: string): wordnode
public addchild(char: string): wordnode
}
從配置表中讀取讀取敏感詞列表,這裡我們使用的是符合 protobuf 語法的配表方式,如下:
cscs
required
required
uint32
string
wordid
dirtyword
髒字id
髒字列表
1敏感詞1
2敏感詞2
......
n敏感詞n
然後通過工具匯出為二進位制格式,在**中解析讀取資料,得到乙個array
:
public static getdirtyarray()
return wordarray;
}
將此列表用於初始化敏感詞索引樹,這裡我將其封裝成乙個單例的工具類來使用:
// 敏感詞過濾器(基於 dfa 演算法)
class dirtywordfilter
if (!this._instance._inited)
return this._instance;
} // 是否已初始化
private _inited: boolean;
// 髒詞庫
private dirtywordarray: array;
// 檢測源字串
private sourceword: string;
// 代替敏感字的字元
private repchar = '*';
// 髒詞庫構造的 dfa 敏感詞索引樹結構
private treeroot: wordnode;
public constructor()
public clean()
// 從髒詞表中讀出髒詞庫
private inittreeconfs() else
}// 詞尾標識
node.isend = true;}}
}this.dirtywordarray = null;
this._inited = true;
} /**
* 檢測乙個詞並返回是否帶敏感詞和替換敏感詞之後的結果
* @param word 檢測的詞
* @param repchar 代替敏感字的字元
*/public filterword(word: string, repchar?: string):
childnode = node.getchild(char);
if (childnode)
}node = childnode;}}
}return ;
} // 替換字串
public getreplacestr(repchar: string, length: number)
return result;
}}
呼叫介面來檢測字串如下:
let = dirtywordfilter.instance.filterword("檢測的字串");
演算法 DFA敏感詞過濾
最近剛好有群友問到關於敏感詞過濾的問題,當時有人給出了一些辦法。1.利用hashset,對傳多來的字串進行比較。或者將敏感詞儲存到資料庫或者其他地方,然後和傳入的詞做匹配。2.正規表示式匹配。上述兩個方法不用想肯定都是很慢的。後來有人說道可以利用dfa演算法,因此我去研究了一下,增加自己的知識面。具...
Java實現DFA演算法實現敏感詞過濾
在實現文字過濾的演算法中,dfa是唯一比較好的實現演算法。dfa即deterministic finite automaton,也就是確定有窮自動機,它是是通過event和當前的state得到下乙個state,即event state nextstate。下圖展示了其狀態的轉換 在這幅圖中大寫字母 ...
遊戲中敏感詞的過濾之DFA演算法
對於乙個遊戲,如果有聊天功能,那麼我們就會希望我們的聊天系統能夠對玩家的輸入進行判斷,如果玩家的輸入中含有一些敏感詞彙,那麼我們就禁止玩家傳送聊天,或者把敏感詞轉換為 來替換。設我們已經有了乙個敏感詞詞庫 從相關部門獲取到的,或者網上找來的 那麼我們最容易想到的過濾敏感詞的方法就是 遍歷整個敏感詞庫...