敏感词过滤

敏感词过滤

2012 年 11 月 25 日

一个简单的敏感词过滤的设计:

  • 最基本的思路是建立hash表来做查询.
  • 敏感词的长度一般不会太长, 一般也就2个汉字(4个字节)左右, 可以再做一份敏感词长度的索引, 这样子在处理时能提高效率.
  • 编码问题: 词库和源因为以往的历史原因, 是 GBK 编码, 而非 UTF.
  • 目前是一个英文忽略大小写的设计.
  • 代码在gbase中, 关键部分的代码如下所示:
// dirty word
typedef struct dirty_t
{
    char word[MAX_DIRTY_WORDS_LEN];
    int prev;
    int next;
} dirty_t;

// dirty context
typedef struct dirty_ctx_t
{
    int table_size;
    dirty_t table[MAX_DIRTY_WORDS_COUNT];
    int hash[MAX_DIRTY_WORDS_HASH_COUNT];
    int index[256][256];
} dirty_ctx_t;

// if > 0x80, means double bytes
// else, single byte
const uint8_t GB_SPEC_CHAR = (uint8_t)(0x80);

// dirty words check
int dirty_check(dirty_ctx_t* ctx, const char* src, int len)
{
    static char lowcase[MAX_SOURCE_WORDS_LEN];
    int i, k, step, key;
    const uint8_t* from;

    if (!ctx || !src || len > MAX_SOURCE_WORDS_LEN) {
        return -3;
    }
    for (i = 0; i < len; i++) {
        lowcase[i] = tolower(src[i]);
    }

    for (i = 0, step = 0; i < len; i += step) {
        key = 0;
        from = (const uint8_t*)&lowcase[i];
        if (from[0] < GB_SPEC_CHAR) {
            key = ctx->index[0][from[0]];
            step = 1;
        } else if (i + 1 < len) {
            key = ctx->index[from[0]][from[1]];
            step = 2;
        } else {
            printf("source code error\n");
            return -2;
        }
        // no index, go ahead
        if (0 == key) {
            continue;
        }
        // found key
        for (k = 1; k < MAX_DIRTY_WORDS_LEN; k++) {
            // exceed len
            if (i + k > len) {
                break;
            }
            // no dirty
            if (0 == CHECK_DIRTY_FLAG(key, k)) {
                continue;
            }
            if (0 == dirty_hash_find(ctx, (const char*)from, k)) {
                return -1;
            }
            // no need to loop all
            RESET_DIRTY_FLAG(key, k);
            if (0 == key) {
                break;
            }
        }
    }
    return 0;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏生信技能树

没有自己的服务器如何学习生物数据分析(下篇)

编者注:在上篇文章《没有自己的服务器如何学习生物数据分析》上篇,我们对 IBM 云计算平台有了基本了解,也学习了如何对数据进行下载上传以及基本的预处理。 在《没...

3447
来自专栏青玉伏案

OracleDBA之表管理

  下面是Oracle表管理的部分,用到的测试表是oracle数据库中scott用户下的表做的测试,有的实验也用到了hr用户的数据,以下这些东西是我的麦库上存的...

1978
来自专栏文渊之博

介绍一种非常好用汇总数据的方式GROUPING SETS

介绍   对于任何人而言,用T-SQL语句来写聚会查询都是工作中重要的一环。我们大家也都很熟悉GROUP BY子句来实现聚合表达式,但是如果打算在一个结果集中包...

38211
来自专栏Python数据科学

【SQL刷题系列】:leetcode178 Rank Scores

编写一个 SQL查询来对分数排名。如果两个分数相同,那么两个分数应该有同样的排名。但也请注意,如果平分,那么下一个名次应该是下一个连续的整数值。换句话说,名次之...

1752
来自专栏james大数据架构

你真的会玩SQL吗?你所不知道的 数据聚合

你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接、外连接 你真的会玩SQL吗?三范式、数据完整性 你真...

2097
来自专栏Jerry的SAP技术分享

会说话的ABAP report

report代码直接call的MS的sound engine,通过sapi.dll暴露出来,

4173
来自专栏技术翻译

编写SQL查询的最佳方法

毫无疑问,编写代码更像是一门艺术,而不是一门科学。即使有经验,每个编码人员也无法编写既可读又可维护的优美代码。一般来说,当您学习编码艺术时,编码会随着经验而提高...

650
来自专栏james大数据架构

你真的会玩SQL吗?冷落的Top和Apply

你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接、外连接 你真的会玩SQL吗?三范式、数据完整性 你真...

2268
来自专栏鸿的学习笔记

Stream和Table的联系

传统的Table领域和目前的Stream领域看似横亘着不可跨越的鸿沟,类似于经典力学和量子力学,但Stream和Table的依然存在着相关性。在研究这个理论之前...

1022
来自专栏WindCoder

MySQL数据库对象与应用-MySQL进阶SQL应用单元测验

1、(单选)有表 song(id,song_name,album,play_count,fav_count)分别表示歌曲的主键id、歌曲名、专辑名、播放次数和收...

1121

扫码关注云+社区