Intereting Posts
Изменение значения внутри цикла foreach не изменяет значение в массиве, который повторяется Получить все фотографии из Instagram, которые имеют определенный хэштегов с PHP PHP Циклические данные, когда форма имеет разные атрибуты имени каждой строки Почему этот CSV не анализируется с помощью fgetcsv? Php Обеспечение уникального имени пользователя dropzone загружает только один файл Не удалось открыть поток: Недопустимый аргумент Предупреждение: mysql_fetch_assoc () ожидает, что параметр 1 будет ресурсом, boolean given Естественный вид заголовков WordPress (в алфавитном и цифровом формате)? Как создать и сохранить пароли md5 в mysql обновление в mysql_query когда-то возвращает null Как настроить nginx для обслуживания приложения Django и сайта WordPress? Как безопасный вход в систему для входа в Dreamweaver PHP? jQuery итерация по столбцу таблицы Как получить идентификатор от URL-адреса в codeigniter?

Создание контрольных сумм Луна

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

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

function Luhn($number, $iterations = 1) { while ($iterations-- >= 1) { $stack = 0; $parity = strlen($number) % 2; $number = str_split($number, 1); foreach ($number as $key => $value) { if ($key % 2 == $parity) { $value *= 2; if ($value > 9) { $value -= 9; } } $stack += $value; } $stack = 10 - $stack % 10; if ($stack == 10) { $stack = 0; } $number[] = $stack; } return implode('', $number); } 

Некоторые примеры:

 Luhn(3); // 37, invalid Luhn(37); // 372, valid Luhn(372); // 3728, invalid Luhn(3728); // 37283, valid Luhn(37283); // 372837, invalid Luhn(372837); // 3728375, valid 

Я проверяю созданные контрольные суммы на этой странице , что я делаю неправильно здесь?


Для справок в будущем здесь приведена рабочая функция.

 function Luhn($number, $iterations = 1) { while ($iterations-- >= 1) { $stack = 0; $number = str_split(strrev($number), 1); foreach ($number as $key => $value) { if ($key % 2 == 0) { $value = array_sum(str_split($value * 2, 1)); } $stack += $value; } $stack %= 10; if ($stack != 0) { $stack -= 10; } $number = implode('', array_reverse($number)) . abs($stack); } return $number; } 

Я сбросил переменную $ parity, так как для этого она не нужна, и для проверки:

 function Luhn_Verify($number, $iterations = 1) { $result = substr($number, 0, - $iterations); if (Luhn($result, $iterations) == $number) { return $result; } return false; } 

Изменить : Извините, теперь я понимаю, что у вас уже был почти весь мой ответ, вы просто неправильно определили, какой фактор использовать для какой цифры.

Весь мой ответ теперь можно суммировать с этим единственным предложением:

У вас коэффициент обратный, вы умножаете неправильные цифры на 2 в зависимости от длины номера.


Взгляните на статью Википедии по алгоритму Луна .

Причина, по которой ваша контрольная сумма недействительна в половине случаев, заключается в том, что с вашими проверками половина времени вашего номера имеет нечетное количество цифр, а затем вы удваиваете неправильную цифру.

Для 37283, при подсчете справа, вы получите эту последовательность чисел:

  3 * 1 = 3 3 8 * 2 = 16 --> 1 + 6 = 7 2 * 1 = 2 2 7 * 2 = 14 --> 1 + 4 = 5 + 3 * 1 = 3 3 = 20 

Алгоритм требует, чтобы вы суммировали отдельные цифры с исходного номера и отдельные цифры продукта этих «каждые две цифры справа».

Итак, справа вы суммируете 3 + (1 + 6) + 2 + (1 + 4) + 3, что дает вам 20.

Если число, в которое вы заканчиваете, заканчивается нулем, что соответствует 20, число действительно.

Теперь, ваш вопрос подсказывает, что вы хотите знать, как сгенерировать контрольную сумму, ну, это легко, сделайте следующее:

  1. Отбросьте лишний ноль, поэтому ваш номер идет от xyxyxyxy до xyxyxyxy0
  2. Вычислить сумму контрольной суммы luhn для нового номера
  3. Возьмите сумму, модуль 10, так что вы получите одну цифру от 0 до 10
  4. Если цифра равна 0, то поздравления, цифра контрольной суммы равна нулю
  5. В противном случае, вычислите 10-значный, чтобы получить то, что вам нужно для последней цифры, вместо этого нуля

Пример: номер 12345

  1. Tack на ноль: 123450
  2. Вычислить контрольную сумму luhn для 123450, что приводит к

     0 5 4 3 2 1 1 2 1 2 1 2 <-- factor 0 10 4 6 2 2 <-- product 0 1 0 4 6 2 2 <-- sum these to: 0+1+0+4+6+2+2=15 
  3. Возьмите сумму (15), модуль 10, что дает вам 5

  4. Цифра (5) не равна нулю
  5. Вычислите 10-5, что дает вам 5, последняя цифра должна быть 5.

Таким образом, результат 123455.

ваш php глючит, он ведет в бесконечный цикл. Это рабочая версия, которую я использую, измененная из вашего кода

функция Luhn ($ number) {

 $stack = 0; $number = str_split(strrev($number)); foreach ($number as $key => $value) { if ($key % 2 == 0) { $value = array_sum(str_split($value * 2)); } $stack += $value; } $stack %= 10; if ($stack != 0) { $stack -= 10; $stack = abs($stack); } $number = implode('', array_reverse($number)); $number = $number . strval($stack); return $number; 

}

Создайте php и запустите в своем локальном хосте Luhn (xxxxxxxx) для подтверждения.

ПЛОХО

Я буквально не могу поверить, сколько там крахмальных реализаций.

IDAutomation имеет сборку .NET с функцией MOD10 () для создания, но она просто не работает. В Reflector код слишком длинный для того, что он должен делать в любом случае.


ПЛОХО

Этот беспорядок на странице, которая в настоящее время связана с Википедией (!) Для Javascript, имеет несколько реализаций проверки, которые даже не возвращают одно и то же значение при вызове каждого из них.


ХОРОШО

Страница, связанная с страницей Luhn из Википедии, имеет кодировщик Javascript, который, похоже, работает:

 // Javascript String.prototype.luhnGet = function() { var luhnArr = [[0,1,2,3,4,5,6,7,8,9],[0,2,4,6,8,1,3,5,7,9]], sum = 0; this.replace(/\D+/g,"").replace(/[\d]/g, function(c, p, o){ sum += luhnArr[ (o.length-p)&1 ][ parseInt(c,10) ] }); return this + ((10 - sum%10)%10); }; alert("54511187504546384725".luhnGet());​ 

ХОРОШО

Эта очень полезная страница EE4253 проверяет контрольную цифру, а также показывает полный расчет и объяснение.


ХОРОШО

Мне нужен код C # и в итоге использовал код кода кода :

 // C# public static int GetMod10Digit(string data) { int sum = 0; bool odd = true; for (int i = data.Length - 1; i >= 0; i--) { if (odd == true) { int tSum = Convert.ToInt32(data[i].ToString()) * 2; if (tSum >= 10) { string tData = tSum.ToString(); tSum = Convert.ToInt32(tData[0].ToString()) + Convert.ToInt32(tData[1].ToString()); } sum += tSum; } else sum += Convert.ToInt32(data[i].ToString()); odd = !odd; } int result = (((sum / 10) + 1) * 10) - sum; return result % 10; } 

ХОРОШО

Этот код проверки на C #, похоже, работает, если он немного громоздкий. Я просто использовал его, чтобы проверить, что это было правильно.

Теперь существует репозиторий github, основанный на исходном вопросе / ответе. Видеть

https://github.com/xi-project/xi-algorithm

Он также доступен в упаковке

Это функция, которая может вам помочь, она коротка, и все работает отлично.

 function isLuhnValid($number) { if (empty($number)) return false; $_j = 0; $_base = str_split($number); $_sum = array_pop($_base); while (($_actual = array_pop($_base)) !== null) { if ($_j % 2 == 0) { $_actual *= 2; if ($_actual > 9) $_actual -= 9; } $_j++; $_sum += $_actual; } return $_sum % 10 === 0; }