zoukankan      html  css  js  c++  java
  • DFA算法的简单说明!

    1.DFA算法简介

    DFA全称为:Deterministic Finite Automaton,即确定有穷自动机。其特征为:有一个有限状态集合和一些从一个状态通向另一个状态的边,每条边上标记有一个符号,其中一个状态是初态,某些状态是终态。但不同于不确定的有限自动机,DFA中不会有从同一状态出发的两条边标志有相同的符号。

    <?php
    /**
     * 敏感词过滤方法.
     */
    
    namespace appcommon	ool;
    
    
    use appcommonmodelSensitive;
    
    class SensitiveTool
    {
        private static $arrHashMap = [];
        private static $file       = ROOT_PATH.'runtime'.DS.'sensitive.txt';
    
        /**
         * 把敏感词保存为文件
         * @return bool|int
         */
        public static function saveSensitiveWord(){
            $data = Sensitive::all();
            foreach( $data as $k => $v ){
                self::addKeyWord($v['name']);
            }
            return file_put_contents(self::$file,serialize(self::$arrHashMap));
    
        }
    
        /**
         * 过滤敏感词
         * @param $strWord
         * @return mixed
         */
        public static function filterSensitiveWord( $strWord ){
            $file = unserialize(file_get_contents(self::$file));
            $resStr  = $strWord;
            if(!empty($file)){
                $len = mb_strlen($strWord, 'UTF-8');
                $arrHashMap = self::$arrHashMap = $file;
                $newWord = '';
                for ($i=0; $i < $len; $i++) {
                    $word = mb_substr($strWord, $i, 1, 'UTF-8');
                    if (!isset($arrHashMap[$word])) {
                        $arrHashMap = self::$arrHashMap;
                        $newWord = '';
                    }
                    $newWord .= $word;
                    if ($arrHashMap[$word]['end']) {
                        $asterisk = self::getAsterisk(mb_strlen($newWord, 'UTF-8'));
                        $resStr = str_replace($newWord,$asterisk,$resStr);
                        $newWord = '';
                        $arrHashMap = self::$arrHashMap;
                    } else{
                        $arrHashMap = $arrHashMap[$word];
    
                    }
                }
            }
    
            return $resStr;
        }
    
        /**
         * 过滤邮箱和手机号(8位以上数字)
         * @param $msg
         * @return string
         */
        public static function filterTelMail( $msg ):string {
            if(is_string((string)$msg)){
                $msg = preg_replace('/d{8,}/', '****', $msg);
                $msg = preg_replace('/[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,})/i', '****', $msg);
            }else{
                $msg = '';
            }
    
            return $msg;
        }
        /**
         * 新增敏感词的核心方法
         * @param $strWord
         */
        private static function addKeyWord( $strWord ) { //免定金峨眉牌汽枪
            $len = mb_strlen($strWord, 'UTF-8');
    
            $arrHashMap = &self::$arrHashMap;
            for ($i=0; $i < $len; $i++) {
                $word = mb_substr($strWord, $i, 1, 'UTF-8');
                // 已存在
                if (isset($arrHashMap[$word])) {
                    if ($i == ($len - 1)) {
                        $arrHashMap[$word]['end'] = 1;
                    }
                } else {
                    // 不存在
                    if ($i == ($len - 1)) {
                        $arrHashMap[$word] = [];
                        $arrHashMap[$word]['end'] = 1;
                    } else {
                        $arrHashMap[$word] = [];
                        $arrHashMap[$word]['end'] = 0;
                    }
                }
                // 传址
                $arrHashMap = &$arrHashMap[$word];
            }
        }
    
        /**
         * 生成*号
         * @param int $num
         * @return string
         */
        private static function getAsterisk( int $num ) :string {
            $str = '';
            for($i=1;$i<=$num;$i++) {
                $str .= '*';
            }
            return $str;
        }
    
    }

    以下是网上优化思路,暂时没有考虑:

    2.优化思路

    2.1敏感词中间填充无意义字符问题

    对于“王*八&&蛋”这样的词,中间填充了无意义的字符来混淆,在我们做敏感词搜索时,同样应该做一个无意义词的过滤,当循环到这类无意义的字符时进行跳过,避免干扰。

    2.2敏感词用拼音或部分用拼音代替

    两种解决思路:一种是最简单是遇到这类问题,先丰富敏感词库进行快速解决。第二种是判断时将敏感词转换为拼音进行对比判断。

    不过目前这两种方案均不能彻底很好的解决该问题,此类问题还需进一步研究。

    参考资源:

    http://www.mamicode.com/info-detail-965728.html

    https://blog.csdn.net/qq_36827957/article/details/74357283

  • 相关阅读:
    Springboot 基于的SAP项目环境配置
    Impala 技术点梳理
    Elasticsearch 使用技巧笔记
    ELK 6.x 部署
    eclipse安装lombok
    IIS服务器管理学习
    Springboot依赖注入笔记
    Eclipse解决乱码问题
    Springboot依赖注入 Service类中使用静态变量
    javascript 操作符类型隐性转换
  • 原文地址:https://www.cnblogs.com/myvic/p/8671991.html
Copyright © 2011-2022 走看看