这两种算法的结果有区别吗?

Hai*_*ood 3 algorithm

这两个算法用于检查有效的会员编号,第一个是我公司给出的,第二个是我设计的,从我的测试我看不出它们之间的功能,

有没有人能看到他们会在哪里返回不同的输出?

test input: 
6014355021355010
or
6014355065446212
or
6014351000254605

校验位使用前15位数字计算如下:

  1. 从左到右对偶数位置的数字求和
  2. 将奇数位置(从左到右)中的每个数字乘以数字2.如果任何结果是2位数,则将数字加总为1.将每次乘法的数字相加到最终结果中.
  3. 添加步骤1和2的最终结果.
  4. 取第3步结果的最后一位数,然后从10减去得到校验位.
  5. 从16位数字中取最后一位数字并与校验位进行比较
  6. 如果它们相等,则有效

VS

校验位使用整数16位数进行计算,如下所示:

  1. 从左到右对偶数位置的数字求和
  2. 将奇数位置(从左到右)中的每个数字乘以数字2.如果任何结果是2位数,则将数字加总为1.将每次乘法的数字相加到最终结果中.
  3. 添加步骤1和2的最终结果.
  4. 取最终结果和模数10
  5. 如果结果为0,则表示有效


更新:
好的.我试图在php中创建这两个算法,第二个,我已经成功创建,但是,第一个,我似乎无法开始工作.

可能我读错了,但是,这是我给第一个算法的原始简介:

16位数模数10校验位计算

校验位使用前15位数字计算如下:
1.从左到右对偶数位置的数字求和

.2.将奇数位置(从左到右)的每个数字乘以数字2
如果有任何结果是2位数,将数字加总为1.
将每次乘法的数字相加到最终结果中.

3.添加步骤1和2的最终结果

.4.从步骤3中取结果的最后一位数,并从10中减去得到校验位.
如果步骤3的结果是10的倍数,则校验位将为零.


6014 3590 0000 0928
1.0 0 + 4 + 5 + 0 + 0 + 0 + 9 = 18
2.0 6*2 = 12 所以 1 + 2 = 3
2.1 1*2 = 2
2.2 3*2 = 6
2.3 9*2 = 18 so 1 + 8 = 9
2.4 0*2 = 0
2.5 0*2 = 0
2.6 0*2 = 0
2.7 2*2 = 4
2.8 3 + 2 + 6 + 9 + 0 + 0 + 0 + 4 = 24
3.0 18 + 24 = 42
4.0校验位为10 - 2 = 8
5.0 8 =第16位(601435900000092 [8])


Update2:
好的,所以我更正了算法,

另外,我应该提一下,如果(长度数!= 16)返回1,还有另外两个检查; 如果(前5个字符!= 601435)返回1;

这有什么反击吗?

欢呼,马特


算法测试[php]

<?php
$file = file_get_contents('fb.csv');
$numbers = explode("\n", $file);

function validate_flybuys($number) {
    $r = array ('o' => '0', 'i' => '1', 'l' => '1', 'e' => '3', ' ' => '');
    $flybuys = trim(strtolower($number));
    $flybuys = str_replace(array_keys($r), $r, $flybuys);
    if('601435' != substr($flybuys, 0, 6) || strlen($flybuys) != 16)
            return 1;
    $evens = 0;
    $odds = '';

    for($i = 0; $i <= 15; $i+=2) {
        $odds .= $flybuys[$i];
        $evens += $flybuys[$i+1];
    }

    $odds = str_split($odds);
    foreach($odds as &$odd) {
        $odd = $odd*2;
        if($odd >= 10) {
            $odd = str_split($odd);
            $odd = $odd[0] + $odd[1];
        }
    }
    return (array_sum($odds)+$evens) % 10;
}

function validate_flybuys2($number) {
    $r = array ('o' => '0', 'i' => '1', 'l' => '1', 'e' => '3', ' ' => '');
    $flybuys = trim(strtolower($number));
    $flybuys = str_replace(array_keys($r), $r, $flybuys);
    if('601435' != substr($flybuys, 0, 6) || strlen($flybuys) != 16)
            return 1;
    $evens = 0;
    $odds = '';

    for($i = 0; $i <= 14; $i+=2) {
        $odds .= $flybuys[$i];
        if($i != 14)
            $evens += $flybuys[$i+1];
    }

    $odds = str_split($odds);
    foreach($odds as &$odd) {
        $odd = $odd*2;
        if($odd >= 10) {
            $odd = str_split($odd);
            $odd = $odd[0] + $odd[1];
        }
    }
    $total = (array_sum($odds))+$evens;
    $total = str_split($total);
    $check = 10 - $total[1];
    $check = $check % 10;
    if($check == substr($flybuys, 15, 1))
        return 0;
    else
        return $check;
}

foreach($numbers as $number) {
    $valid = validate_flybuys($number);
    $valid2 = validate_flybuys2($number);
    if($valid != $valid2 || $valid != 0) {
        echo '<hr />';
        echo 'NUMBER: '.$number.'<br />';
        echo 'V1: '.$valid.'<br />';
        echo 'V2: '.$valid2.'<br />';
    }
}
Run Code Online (Sandbox Code Playgroud)

如果有人有兴趣和评论我可以发布一些样本数来测试:)
哦,并随意优化代码8D

rud*_*ore 6

编辑:此证明仅在第一算法的步骤5和6是等同检查而不是模数计算时才有效.平等检查似乎是评论中提到的原始简报.

EDIT2:我认为第一个算法应该是这样的.但你应该更好地验证这一点,也许应该是给你原始简报的人.

  1. 从左到右对偶数位置的数字求和
  2. 将奇数位置(从左到右)中的每个数字乘以数字2.如果任何结果是2位数,则将数字加总为1.将每次乘法的数字相加到最终结果中.
  3. 添加步骤1和2的最终结果.
  4. 取第3步结果的最后一位数,从10减去得到校验位.
  5. 取16位数的最后一位,如果它与计算的校验位相同,则该数字有效

为了在数学上验证两种算法是相等的,您可以使用一致性.

假设a是第一算法b的步骤3的总和,是第二算法的步骤3的总和,并且c是第16位(校验位).

比之间的差a,并bc被添加到b但不a,这意味着:

a ? b - c mod 10
Run Code Online (Sandbox Code Playgroud)

来自第一算法的检查通过a从10 减去并检查它是否与c模数10 一致来执行.(对于加法和减法,当执行模数时无关紧要)

10 - a ? c mod 10
Run Code Online (Sandbox Code Playgroud)

这相当于:

-a ? c mod 10
Run Code Online (Sandbox Code Playgroud)

现在你可以a用第一个替换,结果是

-(b - c) ? c mod 10
Run Code Online (Sandbox Code Playgroud)

这相当于:

c - b ? c mod 10
Run Code Online (Sandbox Code Playgroud)

这相当于:

-b ? 0 mod 10
b ? 0 mod 10
Run Code Online (Sandbox Code Playgroud)

这是检查,在第二个算法中执行.因此两种算法都返回相同的结果.