duangsuse::Echo
其实虽然对于计算机视觉来说,肯定是比简单的计算机图形学生成算法要耗时的 但是可以考虑有一些算法低劣的 spam bot,没有自动生成图片,沿用老图片在,所以可以保存已经判断为 spam 的图片 hashcode 再发封禁 再不济一点,可以找一下有没有图像的 SimHash 实现,先对比图片像素大小,完全等同就对比哈希码,类似就认为是 spam 图片,或者让机器人自动收集所有是 spam 的图片使用机器学习找出其中类似的像素簇、然后按大小模糊判定再加权回归,是个比执行 OCR 算法要好的方案或许吧(考虑到很少有…
那边可见开发人员的技术也是群水逼,为啥不做自然语言处理算法,也能混久点,这么弄和码农一样的行事风格...
duangsuse::Echo
其实虽然对于计算机视觉来说,肯定是比简单的计算机图形学生成算法要耗时的 但是可以考虑有一些算法低劣的 spam bot,没有自动生成图片,沿用老图片在,所以可以保存已经判断为 spam 的图片 hashcode 再发封禁 再不济一点,可以找一下有没有图像的 SimHash 实现,先对比图片像素大小,完全等同就对比哈希码,类似就认为是 spam 图片,或者让机器人自动收集所有是 spam 的图片使用机器学习找出其中类似的像素簇、然后按大小模糊判定再加权回归,是个比执行 OCR 算法要好的方案或许吧(考虑到很少有…
因为我也不是机器学习和计算机图形学、信息学、密码学领域的人 #machl #ann #cg ....
自然语言处理我也是正在想办法准备学
所以我只好看看关键字匹配... 发现的确就是分词算法啊
https://github.com/CNBlackListR/CNBlackListSoamChecker/blob/aa281efd716a8c11876d755868125cd117aa38cb/CommandObject/SpamMessageChecker.cs#L37
简而言之,spam 打分算法就是接受 SpamMessage 配置和目标判断消息,返回 possibility 值的函数
这个关键字匹配算法虽然优化过,不过也是『简单』算法,因为它还是得判断 n 次加权(一个关键字判断一次,不能扫描一遍消息一起判断了)
具体的匹配算法就是:
如有字符串 "abcde" 关键字列表 [(1, "a"), (2, "de")]
这里要的是匹配,比如我们有字符串
a "hello fish sea world" 和 b "fish"
要判断 b 在 a 里出现了几次,我们可以这样:
枚举 a 里的索引『i』且『i + (b 的长度)小于 a 的长度』(就是所有 b 可能和 a 的某个子序列匹配的索引们)
对于所有 b 里的字符
如果『该字符』等于『a 枚举到的字符』继续判断
假如已经枚举到了最后一个字符,则匹配成功
否则 打断循环,跳过当前字符串的长度 — 我们只需要判断一个字符串,前面的索引 n 都不匹配后面的 x > n 匹配也没有用, skip 掉
好吧,如果你觉得上面的还是难于理解,那么这是一种算法:
它是从这里,Line range 47-75 抽提出来的一种字符序列匹配算法
它有两个输入,String str 和 String part、一个输出,int,返回 str 中 part 子序列的个数
比如 str = "12345ab3243ab..23ab", part = "ab" 输出 3
显然,它要计数数目、检查 str 和 part 相关索引的匹配,有
int count
size si, pi
size matched — 已经匹配的长度
它的逻辑很简单,就是枚举所有 str 和 part 可能重合的索引(str.length - part.length)
(si, pi) =>
再进行
然后得基于当前的 si 位置再进行匹配,如果成功,则 ++count,如果还在判断 ++matched; ++pi; ++si,如果失败 si += (part.length - matched); pi = 0 // 跳过剩余,重新 match
这样碰到显然不是子序列的,直接跳过就好。
如果你还是无法理解,我正在做动态图....
自然语言处理我也是正在想办法准备学
所以我只好看看关键字匹配... 发现的确就是分词算法啊
https://github.com/CNBlackListR/CNBlackListSoamChecker/blob/aa281efd716a8c11876d755868125cd117aa38cb/CommandObject/SpamMessageChecker.cs#L37
简而言之,spam 打分算法就是接受 SpamMessage 配置和目标判断消息,返回 possibility 值的函数
这个关键字匹配算法虽然优化过,不过也是『简单』算法,因为它还是得判断 n 次加权(一个关键字判断一次,不能扫描一遍消息一起判断了)
具体的匹配算法就是:
如有字符串 "abcde" 关键字列表 [(1, "a"), (2, "de")]
foreach kw in kws
if strstr(snd kw, mesg) > 0: points +=
fst kw
而 strstr 是 libc 里的一个字符串搜索子串函数这里要的是匹配,比如我们有字符串
a "hello fish sea world" 和 b "fish"
要判断 b 在 a 里出现了几次,我们可以这样:
枚举 a 里的索引『i』且『i + (b 的长度)小于 a 的长度』(就是所有 b 可能和 a 的某个子序列匹配的索引们)
对于所有 b 里的字符
如果『该字符』等于『a 枚举到的字符』继续判断
假如已经枚举到了最后一个字符,则匹配成功
否则 打断循环,跳过当前字符串的长度 — 我们只需要判断一个字符串,前面的索引 n 都不匹配后面的 x > n 匹配也没有用, skip 掉
好吧,如果你觉得上面的还是难于理解,那么这是一种算法:
它是从这里,Line range 47-75 抽提出来的一种字符序列匹配算法
它有两个输入,String str 和 String part、一个输出,int,返回 str 中 part 子序列的个数
比如 str = "12345ab3243ab..23ab", part = "ab" 输出 3
显然,它要计数数目、检查 str 和 part 相关索引的匹配,有
int count
size si, pi
size matched — 已经匹配的长度
它的逻辑很简单,就是枚举所有 str 和 part 可能重合的索引(str.length - part.length)
(si, pi) =>
再进行
str.subseq[si..].startWith(part) 判断然后得基于当前的 si 位置再进行匹配,如果成功,则 ++count,如果还在判断 ++matched; ++pi; ++si,如果失败 si += (part.length - matched); pi = 0 // 跳过剩余,重新 match
这样碰到显然不是子序列的,直接跳过就好。
如果你还是无法理解,我正在做动态图....
GitHub
CNBlackListR/CNBlackListSoamChecker
Contribute to CNBlackListR/CNBlackListSoamChecker development by creating an account on GitHub.
duangsuse::Echo
好奇怪,这里有个 if (...) {...} else if (x != 0) {...} else { x = 0; } 出现,第二个 else if 已经接受了所有 x != 0 的情况,也就是说最后一个 else 那里 x 显然是 0... 那么这个 x = 0 有什么用...
This media is not supported in your browser
VIEW IN TELEGRAM
越复杂越容易堆砌,越简单越难于设计,好好把脑子用来想该想的东西,这些不良设计实践少做,不然遇到再难写一点的算法,该怎么办?
都去尝试理解你之前写的那些难看的算法了,复杂一点的算法,架构更大,怎么留出脑力去设计真正有用的东西?
重构火葬场?
都去尝试理解你之前写的那些难看的算法了,复杂一点的算法,架构更大,怎么留出脑力去设计真正有用的东西?
重构火葬场?
This media is not supported in your browser
VIEW IN TELEGRAM
duangsuse::Echo
但是没有回应,因为他们吃光了所有牡蛎...
🤔 文本图层和普通图层、移动对象的方法都容易找到,我觉得如果有下次,可以写一个 GIMP 插件来画类似这样的动态图... 甚至可以自动执行过程可视化
总算让人省了一回心... (辣鸡 #Python 的 Unicode 支持不好,我使用 Unicode 符号做图层名,结果 python 索引到的字符串里居然都是不完整编码的,直接区间下标访问不方便,气死
duangsuse::Echo
这个脚本只是需要一个简单的逻辑,来帮助我完成对程序可视化图片的操作
规范大概是这样:
要提供一个 GUI,展示变量列表
List(Label, Textfield)
『同步』操作:利用正则表达式解析所有键值对 (k = v)
『更新』操作:替换原文本为更新值后的文本
这些图层的名字做固定处理即可得到相应数据指针的名字
每个项目都对照到了
提供一个『上移 Code 指针』操作和一个『下移 Code 指针』操作
Code 是一个文本图层,包含程式码,目前仅仅创建 VFS 不需要关心其内容Trace 是一个文本图层,包含变量的追踪要提供一个 GUI,展示变量列表
List(Label, Textfield)
『同步』操作:利用正则表达式解析所有键值对 (k = v)
/(\w+)\s*=\s*(.+)$/ 更新列表『更新』操作:替换原文本为更新值后的文本
Visual 是可视化图层组,包含所有需要可视化的图层这些图层的名字做固定处理即可得到相应数据指针的名字
Vals 是不变量的图层组,其中每个图层都对照了一个 Visual 里的图层,映射方式是 ("v" + x)
目前也只是建模,不做其他考虑Pointers 是可视化指针组,其中项目都是图层组,每个项目都对照到了
Visual 里的图层或 Code,映射方式是 ("p" + x.lower() + "s")
提供一个『更新箭头』操作,根据指定的『Trace 层』变量名自动显示 Trace 层变量指向(数组下标,从 0 起始)并且隐藏前一个箭头的显示(上次设置的箭头)提供一个『上移 Code 指针』操作和一个『下移 Code 指针』操作
duangsuse::Echo
规范大概是这样: Code 是一个文本图层,包含程式码,目前仅仅创建 VFS 不需要关心其内容 Trace 是一个文本图层,包含变量的追踪 要提供一个 GUI,展示变量列表 List(Label, Textfield) 『同步』操作:利用正则表达式解析所有键值对 (k = v) /(\w+)\s*=\s*(.+)$/ 更新列表 『更新』操作:替换原文本为更新值后的文本 Visual 是可视化图层组,包含所有需要可视化的图层 这些图层的名字做固定处理即可得到相应数据指针的名字 Vals 是不变…
需要使用的 GIMP API:
Gimp.message(str)
Gimp.get_foreground()
gimp.Image.layers
gimp.GroupLayer
gimp.Layer
gimp.Layer.visible~bool
gimp.pdb.gimp_text_layer_get_...
gimp.pdb.gimp_text_layer_set_...
如果从 get_text 读取到空,则读取 markup,忽视任何标签解析
替换的时候还要考虑到变更自动变色的选项,自动改为前景色
需要使用的 Tkintr API:
Gimp.message(str)
Gimp.get_foreground()
gimp.Image.layers
gimp.GroupLayer
gimp.Layer
gimp.Layer.visible~bool
gimp.pdb.gimp_text_layer_get_...
gimp.pdb.gimp_text_layer_set_...
如果从 get_text 读取到空,则读取 markup,忽视任何标签解析
替换的时候还要考虑到变更自动变色的选项,自动改为前景色
需要使用的 Tkintr API: