我的(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; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。