有没有在这两个算法的结果有区别吗? [英] is there a difference in the result from these two algorithms?
问题描述
这两种算法是用来检查有效会员数量 第一个是一个,我公司给出, 第二个是我设计的,从我的测试中,我看不出它们之间有什么区别功能,
还有什么情况下任何人都可以看到,他们将返回不同的输出?
测试输入: 6014355021355010 要么 6014355065446212 要么 6014351000254605
的校验位是使用第一15位计算如下:
- 求和数字在偶数编号位置从左至右
- 乘以在奇数位的各数字(从左 右)除以个数2.如果任何结果 是2位,总结数字成一体。 总结了每个数字 乘法为最终结果。
- 添加步骤1和2的最终结果。
- 径的结果的最后一位由步骤3和从10减去至 给校验位。
- 以最后一位数字由16位数字并比较校验码
- 如果他们是平等的,它是有效的
VS
校验位使用的是全体16位calulated如下:
- 求和数字在偶数编号位置从左至右
- 乘以在奇数位的各数字(从左 右)除以个数2.如果任何结果 是2位,总结数字成一体。 总结了每个数字 乘法为最终结果。
- 添加步骤1和2的最终结果。
- 以最终的结果和模数10
- 如果结果是0,它是有效的
更新:
确定这样。我试图在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:我认为第一个算法应该是这样的。但是,你应该更好地谁给你最初简短的一个验证这一点,也许吧。
- 的求和的在偶数位置的数字从左至右的
- 的由数字2乘以在奇数位的各数字(从左至右)。如果任何结果是2位,总结数字成一体。求和从各乘法位数为最终结果。的
- 的添加步骤1和2的最终结果。的
- 的取结果的最后一位数从10第3步和substract给校验位。的
- 的采取16digit号码的最后一位数字,如果是相同的计算校验位的数量是有效的的
要在数学上verifiy这两种算法都是平等的,你可以使用一致性。
假设 A
是从第一算法的步骤3的总和, B
是第3步的总和第二种算法和 C
是第16位(校验位)。
比之间的 A
和 B
是 C $ C $的区别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:
- Sum the digits in the even numbered positions from left to right
- 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.
- Add the final results of steps 1 and 2.
- Take the last digit of the result from step 3 and subtract from 10 to give the check digit.
- Take the last digit from the 16 Digit number and compare to the check digit
- if they are equal, it is valid
vs
The check digit is calulated using the whole 16 digits as follows:
- Sum the digits in the even numbered positions from left to right
- 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.
- Add the final results of steps 1 and 2.
- Take the final result and Modulus 10
- 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.
- Sum the digits in the even numbered positions from left to right
- 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.
- Add the final results of steps 1 and 2.
- Take the last digit of the result from step 3 and substract from 10 to give the check digit.
- 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屋!