発生Luhnチェックサム
-
07-07-2019 - |
質問
多くの実装に関する妥当性の判断のためLuhnチェックサムをも生成します。ただ この しかし私の実験で明らかにするバギーやかわからない裏の論理デルタに変更します。
ためのシェイプを作ってみましたこの機能をはずすべき発生するLuhnチェックサムがあるんだ理解し、生成されたチェックサムを無効とな半分の時間を。
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;
}
落としたドルパリティ変数ではないと思いますので、その目的の確認:
function Luhn_Verify($number, $iterations = 1)
{
$result = substr($number, 0, - $iterations);
if (Luhn($result, $iterations) == $number)
{
return $result;
}
return false;
}
解決
編集:申し訳ありませんが、ほとんどすべての回答が既にあり、どの数字をどの桁に使用するかを誤って決定したことに気付きました。
私の回答全体を次の1つの文で要約できます。
係数が逆になり、数字の長さに応じて間違った数字に2を掛けています。
Luhnアルゴリズムに関するウィキペディアの記事をご覧ください。
チェックサムが半分の時間無効である理由は、チェックでは半分の時間に数字の桁数が奇数であるため、間違った数字を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
アルゴリズムでは、元の数字の個々の数字と、「右から2桁ごと」の積の個々の数字を合計する必要があります。
つまり、右側から合計すると3 +(1 + 6)+ 2 +(1 + 4)+ 3となり、20になります。
20で終わる0で終わる数値で終わる場合、その数値は有効です。
今、あなたの質問は、あなたがチェックサムを生成する方法を知りたいということを示唆しています。まあ、それは簡単です、次のことをしてください:
- 余分なゼロを追加すると、番号がxyxyxyxyからxyxyxyxy0になります
- 新しい番号のluhnチェックサムの合計を計算します
- 合計、モジュラス10を取得して、0〜10の1桁を取得します
- 数字が0の場合、おめでとうございます、チェックサム数字はゼロでした
- それ以外の場合、10桁を計算して、ゼロではなく最後の桁に必要なものを取得します
例:数値は12345です
- ゼロのタック:123450
-
123450のluhnチェックサムを計算します。これにより、
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
-
合計(15)、モジュラス10を取得すると、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)で実行して確認します。
悪
しかできないどのように多くのcrummyの実装があります。
IDAutomationは .純で組み立てMOD10()関数 の作成がそれだけではなさそうです。光のコードはもう本イベントは終了いたしました。する必要があります。
悪
この混乱のページ することであり、それは、現在のリンクからWikipedia(!) Javascriptは、複数の検証の実装となっても同じ値を返します呼び出す事ができます。
良い
の ページのリンクからWikipediaの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#コードで記述 うがり不格好になる。って使用されたばかりを確認することとしており、上記の正しい。
これはあなたを助けることができる関数であり、短くてうまく動作します。
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;
}