编程语言
首页 > 编程语言> > php – 针对已知字符串列表检查字符串中常见的错误识别字符

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, $pos, 1);
                if ($char === $letter && !in_array($addNumber, $possibles)) {
                    $possibles[] = $addNumber;
                }
                if ($char === $number && !in_array($addLetter, $possibles)) {
                    $possibles[] = $addLetter;
                }
            }
        }
    }
    return $possibles;
}

标签:php,php-5-5
来源: https://codeday.me/bug/20190612/1224771.html