有没有在这两个算法的结果有区别吗? [英] is there a difference in the result from these two algorithms?

查看:122
本文介绍了有没有在这两个算法的结果有区别吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这两种算法是用来检查有效会员数量 第一个是一个,我公司给出, 第二个是我设计的,从我的测试中,我看不出它们之间有什么区别功能,

还有什么情况下任何人都可以看到,他们将返回不同的输出?

测试输入:
6014355021355010
要么
6014355065446212
要么
6014351000254605

的校验位是使用第一15位计算如下:

  
      
  1. 求和数字在偶数编号位置从左至右
  2.   
  3. 乘以在奇数位的各数字(从左   右)除以个数2.如果任何结果   是2位,总结数字成一体。   总结了每个数字   乘法为最终结果。
  4.   
  5. 添加步骤1和2的最终结果。
  6.   
  7. 径的结果的最后一位由步骤3和从10减去至   给校验位。
  8.   
  9. 以最后一位数字由16位数字并比较校验码
  10.   
  11. 如果他们是平等的,它是有效的
  12.   

VS

校验位使用的是全体16位calulated如下:

  
      
  1. 求和数字在偶数编号位置从左至右
  2.   
  3. 乘以在奇数位的各数字(从左   右)除以个数2.如果任何结果   是2位,总结数字成一体。   总结了每个数字   乘法为最终结果。
  4.   
  5. 添加步骤1和2的最终结果。
  6.   
  7. 以最终的结果和模数10
  8.   
  9. 如果结果是0,它是有效的
  10.   


更新:
确定这样。我试图在PHP创建这两个算法, 第二个,我已经成功地创建, 第但是,我不能去上班。

可能是我看过这个错误,但是,原来这里是短暂的,我得到的第一个算法:

  

16位数模数10校验位计算

     

校验位是使用前15位数字如下计算:
   1 总和数字在偶数位置由左到右
  
2 乘以每个数字在奇数编号的位置(从左至右)由数字2
  如果任何结果是2位,总结数字成一体。
  求和从各乘法位数为最终结果。
  
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的所以 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_get_contents('fb.csv');
$数=爆炸(\ N,$文件);

功能validate_flybuys($编号){
    $ R =阵列('O'=>'0','我'=>'1','L'=>'1','E'=>'3',''=> '');
    $ flybuys =修剪(用strtolower($编号));
    $ flybuys = str_replace函数(array_keys($ R),$ R,$ flybuys);
    如果('601435'!= SUBSTR($ flybuys,0,6)||的strlen($ flybuys)!= 16)
            返回1;
    $找齐= 0;
    $赔率='';

    为($ i = 0; $ I< = 15; $ I + = 2){
        $赔率= $ flybuys [$ i]。
        $埃文斯+ = $ flybuys [$ I + 1];
    }

    $赔率= str_split($可能性);
    的foreach($赔率为&放大器; $奇){
        $奇数= $奇* 2;
        如果($奇> = 10){
            $奇数= str_split($奇);
            $奇= $奇数[0] + $奇数[1];
        }
    }
    返程(array_sum($赔率)+ $埃文斯)%10;
}

功能validate_flybuys2($编号){
    $ R =阵列('O'=>'0','我'=>'1','L'=>'1','E'=>'3',''=> '');
    $ flybuys =修剪(用strtolower($编号));
    $ flybuys = str_replace函数(array_keys($ R),$ R,$ flybuys);
    如果('601435'!= SUBSTR($ flybuys,0,6)||的strlen($ flybuys)!= 16)
            返回1;
    $找齐= 0;
    $赔率='';

    为($ i = 0; $ I< = 14; $ I + = 2){
        $赔率= $ flybuys [$ i]。
        如果($ I!= 14)
            $埃文斯+ = $ flybuys [$ I + 1];
    }

    $赔率= str_split($可能性);
    的foreach($赔率为&放大器; $奇){
        $奇数= $奇* 2;
        如果($奇> = 10){
            $奇数= str_split($奇);
            $奇= $奇数[0] + $奇数[1];
        }
    }
    $总额=(array_sum($赔率))+ $找齐;
    $总额= str_split($总);
    $检查= 10  -  $总[1];
    $检查= $支票%10;
    如果($支票== SUBSTR($ flybuys,15,1))
        返回0;
    其他
        返回$检查;
}

的foreach($数为$号){
    $有效= validate_flybuys($号);
    $ valid2 = validate_flybuys2($号);
    如果($有效!= $ valid2 || $有效!= 0){
        回声'<小时/>';
        。回声号:$号< BR />';。
        回声V1:$有效的'< BR />';。
        回声V2:$ valid2'< BR />';。
    }
}
 

如果有人有兴趣和意见,我可以张贴一些样本数来测试对:)
哦,并随时优化Ç8D的$ C $

解决方案

编辑:这证明只能如果所述第一算法的步骤5和6是一个相等检查,而不是一个模数计算。在等于支票似乎是由如上述评价原始简要指

EDIT2:我认为第一个算法应该是这样的。但是,你应该更好地谁给你最初简短的一个验证这一点,也许吧。

  
      
  1. 求和的在偶数位置的数字从左至右
  2.   
  3. 由数字2乘以在奇数位的各数字(从左至右)。如果任何结果是2位,总结数字成一体。求和从各乘法位数为最终结果。
  4.   
  5. 添加步骤1和2的最终结果。
  6.   
  7. 取结果的最后一位数从10第3步和substract给校验位。
  8.   
  9. 采取16digit号码的最后一位数字,如果是相同的计算校验位的数量是有效的
  10.   

要在数学上verifiy这两种算法都是平等的,你可以使用一致性

假设 A 是从第一算法的步骤3的总和, B 是第3步的总和第二种算法和 C 是第16位(校验位)。

比之间的 A B C 添加到 B 而不是 A ,这意味着:

  A≡b  - Çmod10
 

这是第一个算法的检查是通过减去 A 10,并检查它是否是一致的 C 的实施模量10(加法和减法它当进行模数不物质)

  10  - 一个≡çmod10
 

这等于:

  -a≡Çmod10
 

现在您也可以替换 A 与第一位的,这将导致

   - (B  -  C)≡çmod10
 

这等于:

 Ç -  B≡Çmod10
 

这等于:

  -b≡0模10
b≡0模10
 

和是这样的检查,这是在第二算法来执行。所以这两种算法返回相同的结果。

these two algorithms are used to check valid member numbers the first is the one I was given by the company, the second is one I devised, from my tests I can't see any difference between them functionally,

are there any cases anyone can see where they would return different outputs?

test input: 
6014355021355010
or
6014355065446212
or
6014351000254605

The check digit is calculated using the first 15 digits as follows:

  1. Sum the digits in the even numbered positions from left to right
  2. Multiply each digit in the odd numbered positions (from left to right) by the number 2. If any results are 2 digits, sum the digits into one. Sum the digits from each multiplication into a final result.
  3. Add the final results of steps 1 and 2.
  4. Take the last digit of the result from step 3 and subtract from 10 to give the check digit.
  5. Take the last digit from the 16 Digit number and compare to the check digit
  6. if they are equal, it is valid

vs

The check digit is calulated using the whole 16 digits as follows:

  1. Sum the digits in the even numbered positions from left to right
  2. Multiply each digit in the odd numbered positions (from left to right) by the number 2. If any results are 2 digits, sum the digits into one. Sum the digits from each multiplication into a final result.
  3. Add the final results of steps 1 and 2.
  4. Take the final result and Modulus 10
  5. If the result is 0, it is valid


Update:
ok so. I have tried to create both these algorithms in php, the second one, i have created successfully, the first however, i can not seem to get to work.

possibly i have read this wrong, but, here is the original brief i was given for the first algorithm:

16 digit number modulus 10 check digit calculation

The check digit is calculated using the first 15 digits as follows:
1. Sum the digits in the even numbered positions from left to right

2. Multiply each digit in the odd numbered positions (from left to right) by the number 2
If any results are 2 digits, sum the digits into one.
Sum the digits from each multiplication into a final result.

3. Add the final results of steps 1 and 2.

4. Take the last digit of the result from step 3 and subtract from 10 to give the check digit.
If the result of step 3 is a multiple of 10, then the check digit will be zero.


Example 6014 3590 0000 0928
1.0 0 + 4 + 5 + 0 + 0 + 0 + 9 = 18
2.0 6 * 2 = 12 so 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 The check digit is 10 - 2 = 8
5.0 8 = the 16th digit (601435900000092[8])


Update2:
ok, so i have corrected the algorithm,

also, i should mention, that there are two other checks if(length of number != 16) return 1; and if(first 5 characters != 601435) return 1;

so are there any counters to this?

cheers, Matt


Algorithm test [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 />';
    }
}

if anyone is interested and comments i can post some sample numbers to test against :)
oh and feel free to optimize the code 8D

解决方案

EDIT: This proof only works if the step 5 and 6 of the first algorithm are an equal check instead of a modulus calculation. The equal check seems to be meant by the original brief as mentioned in the comments.

EDIT2: I think the first algorithm should look like this. But you should better verify this, maybe from the one who gave you the original brief.

  1. Sum the digits in the even numbered positions from left to right
  2. Multiply each digit in the odd numbered positions (from left to right) by the number 2. If any results are 2 digits, sum the digits into one. Sum the digits from each multiplication into a final result.
  3. Add the final results of steps 1 and 2.
  4. Take the last digit of the result from step 3 and substract from 10 to give the check digit.
  5. Take the last digit of the 16digit-number and if it is the same as the computed check digit the number is valid


To verifiy mathematically that both algorithms are equal you can use congruency.

Let's say a is the sum from step 3 of the first algorithm, b is the sum of step 3 of the second algorithm and c is the 16th digit (the check digit).

Than the difference between a and b is that c is added to b but not to a, which means:

a ≡ b - c mod 10

The check from the first algorithm is performed by substracting a from 10 and check if it is congruent c for modulus 10. (for addition and substraction it doesn't matter when the modulus is performed)

10 - a ≡ c mod 10

this is equal to:

-a ≡ c mod 10

Now you can substitute a with the first one, which results in

-(b - c) ≡ c mod 10

this is equal to:

c - b ≡ c mod 10

and this is equal to:

-b ≡ 0 mod 10
b ≡ 0 mod 10

and that is the check, which is performed in the second algorithm. So both algorithms returns the same result.

这篇关于有没有在这两个算法的结果有区别吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆