php – 针对已知字符串列表检查字符串中常见的错误识别字符
背景
我的(MySQL)数据库中有一个包含六(6)个字符的代码列表.它们由随机选择的数字和字母组成.它们被视为不区分大小写,但它们在数据库中以大写形式存储.它们可能由数字0组成,但从不包含字母O.我将这些代码用作用户的一次性身份验证. 问题 这些代码已在卡片上手写,不幸的是,某些字母和数字可能与某些人看起来相似.这就是为什么我最初没有使用字母O,因为它与手写的0很接近. 到目前为止我做了什么 我能够针对用户输入检查代码(不区分大小写)并确定它是否完全匹配.如果不是我默默地用0替换任何O,然后再试一次. 题 我的问题是,我如何才能为其他字母和数字执行此操作,例如我在下面列出的那些字母和数字,并且仍然相对自信我不会将用户身份验证为不是他人?在这种情况下,两个字符都可以存在于代码中.我已经看过PHP(http://php.net/manual/en/function.levenshtein.php)中的Levenshtein函数以及similar_text()(http://php.net/manual/en/function.similar-text.php),但这两者都不是我想要的,所以我想我可能必须自己动手(可能使用它们)来实现这一点. 相似的字符: S <=> 5 G <=> 6 I <=> 1 解决方法
您描述的问题实际上是哈希冲突.您有多个可能的输入值,并且希望它们分解为单个明确的键.我有几个想法.
正如@bishop建议的那样,你真正需要确定的是,任何给定的输入是否明确无误.我的方法虽然略有不同: 对于任何给定的输入,我将生成所有可能匹配键的列表,并在数据库中查询整个列表.如果只返回一个结果,则没有问题,您可以根据该单个记录继续.在这种情况下,如果用户输入ABCDE5或ABCDES并不重要,因为数据库中只有一个可能匹配任何一个. 但是,如果返回多个结果,则无法确定用户的输入是否准确或是否是错误键入的. (事后看来,设计钥匙最好是没有任何模糊的字符对是可能的.例如,只允许“S”和不允许“5”允许你保证只有一个匹配对于任何给定的输入,无论用户输入“S”还是“5”,因为您总是可以安全地将输入中看到的任何5个转换为S,因为他们知道输入错误.事实上,根据确切的值,您可能是能够追溯修改数据库中的许多或所有密钥以遵循此规则,并使查找不那么麻烦.) 无论如何,在那个模糊的情况下,我认为你没有别的选择,只能回到用户并要求他们重新检查他们的输入,希望在屏幕上的消息中解释可能的问题. 编辑: 以下是根据实际提供的单个输入生成用户要输入的可能值的示例: <?php $inputs = [ 'ABCDEF',// No ambiguity,DB should return 0 or 1 match. 'AAAAA1',// One ambiguous char,user could have meant `AAAAAI` // instead so search DB for both. '156ISG',// Worst case. If the DB values overlap a lot,there // wouldn't be much hope of "guessing" what the user // actually meant. ]; foreach ($inputs as $input) { print_r(generatePossibleMatches($input)); } //---------------------------------------- function generatePossibleMatches($input) { $input = strtoupper($input); $ambiguous = [ 'I' => '1','G' => '6','S' => '5',]; $possibles = [$input]; foreach ($ambiguous as $letter => $number) { foreach ($possibles as $possible) { foreach (str_split($possible) as $pos => $char) { $addNumber = substr_replace($possible,$number,$pos,1); $addLetter = substr_replace($possible,$letter,1); if ($char === $letter && !in_array($addNumber,$possibles)) { $possibles[] = $addNumber; } if ($char === $number && !in_array($addLetter,$possibles)) { $possibles[] = $addLetter; } } } } return $possibles; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |