54

用于识别 [可能的] 机器人生成的用户名。

假设您有一个像“bilbomoothof”这样的用户名......这可能是胡说八道,但它仍然包含可发音的声音,因此看起来是人为生成的。

我接受它可能是从音节字典或单词部分随机生成的,但让我们暂时假设所讨论的机器人有点垃圾。

  1. 假设您有一个像“sdfgbhm342r3f”这样的用户名,对于人类来说,这显然是一个随机字符串。但这可以通过编程方式识别吗?
  2. 是否有任何可用的算法(类似于 Soundex 等)可以识别这样的字符串中的可发音声音?

适用于 PHP/MySQL 的解决方案最受赞赏。

4

10 回答 10

16

我想如果你能把自己限制在英语发音的范围内,你可能会想到类似的东西。对我(我是法国人)来说,像szczepanwawrzyniec这样的词是不可发音的,而且肯定有一定的随机性。

但他们实际上是波兰人的名字(意思是stevenLawrence)......

于 2009-07-22T09:59:35.540 回答
8

我同意麦克。但更重要的是,人们有时拥有无法发音的用户名,例如 qwerty 或 rtfmorleave。

为什么要为此烦恼?

<过时和错误,但我不会因为评论而删除>

但更重要的是,没有机器人使用'zetztzgsd'作为用户名,他们有实名字典,可能的昵称等,所以我认为这对你来说是浪费时间

</ / 过时和假的,但我不会因为评论而删除>

于 2009-07-22T10:03:02.537 回答
8

查找 n-gram 分析。它成功地用于自动检测文本语言,即使在非常短的文本上也能很好地工作。

在线演示(不再在线)将“bilbomoothof”识别为英语,将“sdfgbhm342r3f”识别为尼泊尔语。它可能总是返回最好的匹配,即使它是一个非常糟糕的匹配。我认为您可以训练它辨别“可发音”和“随机”。

于 2009-07-22T11:20:07.560 回答
3

只需在注册过程中使用CAPTCHA

你永远无法区分真正的用户名和机器人创建的用户名,否则会严重惹恼你的用户。

您将阻止使用奇怪或非英文名称的用户,这会激怒他们,并且机器人将继续尝试,直到他们找到一个好的用户名(来自字典或其他来源 -这是一个非常好的用户名,顺便说一句! )。

编辑:寻找预防而不是事后分析?

解决方案是让其他人为您管理用户的身份。例如,您可以使用一小部分 OpenID 提供程序(如 SO)或facebook connect,或两者兼而有之。您将确定用户是真实的,并且他们已经解决了至少一个 CAPTCHA。

编辑:另一个想法

在 Google 中搜索该字符串,并检查找到的匹配项数。不应该是您唯一的工具,但它也是一个很好的指标。当然,随机字符串应该很少或没有匹配。

于 2009-07-22T10:51:27.150 回答
2

您可以使用神经网络来评估昵称是否看起来像自然语言昵称。

组装两个数据集:一个是有效的昵称,一个是伪造的昵称。以字符值作为输入,训练一个简单的反向传播单隐藏层神经网络。神经网络将学习区分“zrgssgbt”和“zargbyt”等字符串,因为后者混合了辅音和元音。

使用真实世界的例子来获得一个好的鉴别器是很重要的。

于 2009-07-22T11:02:30.997 回答
2

回复问题#1:

不幸的是,这是无法做到的,因为Kolmogorov 复杂度函数是不可计算的,因此您无法生成这样的算法,除非您将一些规则应用于可能的用户名域,然后您将能够执行启发式分析并做出决定,但即便如此它真的难做。

PS:发布此答案后,我遇到了一些服务,该服务给出了用户名域限制示例的想法,让用户使用知名公共域的邮箱作为用户名。

于 2009-07-22T09:55:03.317 回答
2

在我的脑海中,您可以使用soundex查找音节。这就是我要探索的方向,基于一个可发音的单词至少有一个音节的假设。

编辑:这是一个计算音节的函数:

function count_syllables($word) {
 
$subsyl = Array(
'cial'
,'tia'
 ,'cius'
 ,'cious'
 ,'giu'
 ,'ion'
 ,'iou'
 ,'sia$'
 ,'.ely$'
 );
  
 $addsyl = Array(
 'ia'
 ,'riet'
 ,'dien'
 ,'iu'
 ,'io'
 ,'ii'
 ,'[aeiouym]bl$'
 ,'[aeiou]{3}'
 ,'^mc'
 ,'ism$'
 ,'([^aeiouy])\1l$'
 ,'[^l]lien'
 ,'^coa[dglx].'
 ,'[^gq]ua[^auieo]'
 ,'dnt$'
 );
  
 // Based on Greg Fast's Perl module Lingua::EN::Syllables
 $word = preg_replace('/[^a-z]/is', '', strtolower($word));
 $word_parts = preg_split('/[^aeiouy]+/', $word);
 foreach ($word_parts as $key => $value) {
 if ($value <> '') {
 $valid_word_parts[] = $value;
 }
 }
  
 $syllables = 0;
 // Thanks to Joe Kovar for correcting a bug in the following lines
 foreach ($subsyl as $syl) {
 $syllables -= preg_match('~'.$syl.'~', $word);
 }
 foreach ($addsyl as $syl) {
 $syllables += preg_match('~'.$syl.'~', $word);
 }
 if (strlen($word) == 1) {
 $syllables++;
 }
 $syllables += count($valid_word_parts);
 $syllables = ($syllables == 0) ? 1 : $syllables;
 return $syllables;
 }

从这个非常有趣的链接:

http://www.addedbytes.com/php/flesch-kincaid-function/

于 2009-07-22T09:56:27.217 回答
0

我不知道这个问题的现有算法,但我认为它可以通过以下任何一种方式受到攻击:

  • 你的机器人可能很垃圾,但你可以保留一个音节列表,或者更具体地说,音素,你可以尝试在给定的字符串中查找。但这听起来有点困难,因为您需要在不同的地方分割字符串等。
  • 英文字母表中有5个元音,还有21个。您可以假设,如果它们是随机生成的,那么您大约会期望 5/26*W(其中 W 是字长)作为元音的字母,并且与此的显着偏差可能是可疑的。(如果包含字母,则 5/31 等等..)您可以尝试通过搜索双胞胎来构建这个想法,并尝试确保每个双胞胎以相同的概率发生等。
  • 此外,您可以尝试围绕元音分割您的输入字符串,例如元音之前的三个字母和元音之后的三个字母,并尝试通过与音素比较来确定它是否发出可识别的声音。
于 2009-07-22T10:00:45.553 回答
0

在俄语中,我们禁止使用音节,例如ГЙаЪЬ在元音之后等等。

然而,垃圾邮件机器人只使用名字数据库,这就是为什么我的垃圾邮件收件箱里充满了你只能在历史书中遇到的奇怪名字。

我希望英语也有音节分布直方图(例如ETAOIN SHRDLU,但是对于两个字母甚至三个字母的音节),并且在一个名称中具有临界密度的低频音节肯定是一个标志。

于 2009-07-22T10:01:28.233 回答
0

请注意,许多大型网站建议使用 [first init][middle init][last name][number] 之类的用户名。然后用户将这些用户名带到其他站点,前三个字母肯定是不发音的。

于 2009-07-28T01:52:10.163 回答