есть ли разница в результате этих двух алгоритмов? - PullRequest
3 голосов
/ 14 июля 2010

эти два алгоритма используются для проверки действительных номеров участников первый - тот, который мне дал компания, второе - это то, что я разработал, из своих тестов я не вижу никакой разницы между ними функционально,

Есть ли случаи, когда кто-нибудь может увидеть, где они будут возвращать разные результаты?

test input: 
6014355021355010
or
6014355065446212
or
6014351000254605

Контрольная цифра рассчитывается с использованием первых 15 цифр следующим образом:

  1. Суммируйте цифры в четных позициях слева направо
  2. Умножить каждую цифру в нечетных позициях (слева направо справа) по номеру 2. Если есть какие-либо результаты 2 цифры, суммируйте цифры в одну. Суммируйте цифры от каждого умножение в конечный результат.
  3. Добавьте окончательные результаты шагов 1 и 2.
  4. Возьмите последнюю цифру результата из шага 3 и вычтите из 10 до введите контрольную цифру.
  5. Возьмите последнюю цифру из 16-значного номера и сравните с контрольной цифрой
  6. если они равны, это действительно

против

Контрольная цифра вычисляется с использованием целых 16 цифр следующим образом:

  1. Суммируйте цифры в четных позициях слева направо
  2. Умножить каждую цифру в нечетных позициях (слева направо справа) по номеру 2. Если есть какие-либо результаты 2 цифры, суммируйте цифры в одну. Суммируйте цифры от каждого умножение в конечный результат.
  3. Добавьте окончательные результаты шагов 1 и 2.
  4. Возьмите конечный результат и модуль 10
  5. Если результат равен 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])

<ч /> Обновление2:
хорошо, я исправил алгоритм,

также, я должен отметить, что есть еще две проверки if (длина номера! = 16) возврат 1; а также if (первые 5 символов! = 601435) возврат 1;

так есть какие-нибудь счетчики к этому?

ура, Matt


Проверка алгоритма [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 />';
    }
}

если кто-то заинтересован и комментирует, я могу опубликовать несколько образцов для проверки:)
ох и не стесняйтесь оптимизировать код 8D

Ответы [ 4 ]

6 голосов
/ 14 июля 2010

РЕДАКТИРОВАТЬ: Это доказательство работает только в том случае, если шаги 5 и 6 первого алгоритма являются равной проверки вместо расчета модуля. Равная проверка, по-видимому, подразумевается в оригинальной записке, упомянутой в комментариях.

EDIT2: я думаю, что первый алгоритм должен выглядеть следующим образом. Но вам лучше проверить это, возможно, от того, кто дал вам оригинальное резюме.

  1. Суммируйте цифры в четных позициях слева направо
  2. Умножьте каждую цифру в нечетных позициях (слева направо) на число 2. Если какой-либо результат представляет собой 2 цифры, сложите цифры в одну. Суммируйте цифры от каждого умножения в окончательный результат.
  3. Добавьте окончательные результаты шагов 1 и 2.
  4. Возьмите последнюю цифру результата из шага 3 и вычтите из 10, чтобы получить контрольную цифру.
  5. Возьмите последнюю цифру 16-значного числа, и если она совпадает с вычисленной контрольной цифрой, то число является действительным

Для математической проверки того, что оба алгоритма равны, вы можете использовать congruency .

Скажем, a - это сумма шага 3 первого алгоритма, b - сумма шага 3 второго алгоритма, c - 16-я цифра (контрольная цифра).

Чем разница между a и b в том, что c добавляется к b, но не к a, что означает:

a ≡ b - c mod 10

Проверка по первому алгоритму выполняется путем вычитания a из 10 и проверки, является ли он конгруэнтным c для модуля 10. (Для сложения и вычитания не имеет значения, когда выполняется модуль)

10 - a ≡ c mod 10

это равно:

-a ≡ c mod 10

Теперь вы можете заменить a первым, в результате чего

-(b - c) ≡ c mod 10

это равно:

c - b ≡ c mod 10

и это равно:

-b ≡ 0 mod 10
b ≡ 0 mod 10

и это проверка, которая выполняется во втором алгоритме. Таким образом, оба алгоритма возвращают один и тот же результат.

2 голосов
/ 14 июля 2010

Edit2: Пожалуйста, смотрите мой другой ответ со встречным примером с правильными алгоритмами.

Редактировать: я использовал 15, а не 16 чисел во втором алгоритме.

Они не эквивалентны.

Возьмем 383838383838383-6, который действителен для первого алгоритма, но второй алгоритм дает 4 в качестве контрольной цифры! = 0.

Изменить: Суммы 56 для четной части и 48 для нечетной, сумма составляет 104.

0 голосов
/ 15 июля 2010

У вашего php-кода есть некоторые проблемы.

$check = 10 - $total[1]; действительно только в том случае, если общая сумма представляет собой двузначное число.Поскольку ваши номера всегда начинаются с 601435, общая сумма не менее 2 цифр.Но по крайней мере 6014359999999990 и 6014359999999999 будут проверены неправильно в V2.

Строка return $check; может возвращать 0. Таким образом 6014355021355012 или 6014355021355017 проверяются как действительные, в то время как онине.

Я бы заменил строки:

$total = str_split($total);
$check = 10 - $total[1];
$check = $check % 10;
if($check == substr($flybuys, 15, 1))
    return 0;
else
    return $check;

на

return (substr($flybuys, 15, 1) + $total) % 10;

Так что V1 и V2 возвращает одно и то же значение.

0 голосов
/ 14 июля 2010

Алгоритмы: разные :

Take 0000000000000257

Исходный алгоритм говорит, что он недействителен: сумма четных цифр равна 2, сумма шансов равна1 => всего 3. 10-3 = 7. 257 MOD 7 = 5! = 0 => Недействительно

Ваш алгоритм суммирует даже 9, шансы 1 => всего 10. 10 MOD 10 == 0 => Действительный.

Таким образом, они не эквивалентны

qed.: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...