Frage

Es gibt viele Implementierungen für Prüfsummen Luhn Validierung, aber nur sehr wenige für sie zu erzeugen. Ich habe jedoch rel="noreferrer"> diese über

ich diese Funktion gemacht haben, die angeblich sollte Luhn Prüfsummen erzeugt, aber aus irgendeinem Grund, dass ich noch nicht die generierten Prüfsummen sind ungültig Hälfte der Zeit verstanden.

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);
}

Einige Beispiele:

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

Ich bin Validierung der erzeugten Prüfsummen gegen diese Seite , was ich falsch hier?


Für die Zukunft, hier ist die Arbeitsfunktion.

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;
}

Ich ließ den $ Parität variabel, da wir es nicht brauchen für diesen Zweck, und zu überprüfen:

function Luhn_Verify($number, $iterations = 1)
{
    $result = substr($number, 0, - $iterations);

    if (Luhn($result, $iterations) == $number)
    {
        return $result;
    }

    return false;
}
War es hilfreich?

Lösung

Bearbeiten :. Sorry, ich weiß jetzt, dass man fast schon meine ganze Antwort war, hatte man nur falsch bestimmt, welcher Faktor für die Ziffer zu verwenden

Meine ganze Antwort jetzt aufsummiert mit diesem einzigen Satz werden kann:

Sie haben den Faktor umgekehrt, sind Sie die falschen Ziffern durch 2 multipliziert wird auf der Länge der Zahl abhängig.


Werfen Sie einen Blick auf die Wikipedia-Artikel auf dem Luhn-Algorithmus .

Der Grund Ihrer Prüfsumme ungültig ist die Hälfte der Zeit ist, dass mit Kontrollen, die Hälfte der Zeit, um Ihre Zahl eine ungerade Anzahl von Ziffern hat, und dann verdoppeln Sie die falsche Ziffer.

Für 37283, wenn von rechts gezählt, können Sie diese Folge von Zahlen erhalten:

  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

Der Algorithmus erfordert, dass Sie die einzelnen Ziffern von der ursprünglichen Zahl zu summieren, und die einzelnen Ziffern des Produkts dieser „alle zwei Ziffern von rechts“.

So von rechts, summieren Sie 3 + (1 + 6) + 2 + (1 + 4) + 3, die Sie 20 gibt.

Wenn die Zahl, die Sie mit den Enden mit einer Null am Ende, der 20 der Fall ist, die Nummer gültig ist.

Nun, Ihre Frage deutet auf Sie wollen wissen, wie die Prüfsumme zu erzeugen, na ja, das ist einfach, gehen Sie wie folgt vor:

  1. Tack auf einem extra Null, so dass Ihre Zahl von xyxyxyxy geht an xyxyxyxy0
  2. Berechnen Sie die Luhn Prüfsumme Summe für die neue Nummer
  3. Nehmen Sie die Summe, Modul 10, so dass Sie eine einzelne Ziffer von 0 bis 10 erhalten
  4. Wenn die Ziffer 0, dann herzlichen Glückwunsch, Ihre Prüfsummenziffer war eine Null
  5. Ansonsten berechnen 10-stellige zu bekommen, was Sie für die letzte Stelle müssen, statt dass Null

Beispiel: Anzahl ist 12345

  1. Tack auf Null: 123450
  2. die Luhn Prüfsumme für 123.450 berechnen, was dazu führt,

    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. Nehmen Sie die Summe (15), Modul 10, die Sie 5

  4. gibt
  5. Digit (5), ist nicht Null
  6. berechnen 10-5, die Sie 5, die letzte Ziffer gibt sollte 5.

Das Ergebnis ist also 123.455.

Andere Tipps

Ihre PHP ist fehlerhaft, es führt in eine Endlosschleife. Dies ist die Arbeitsversion, die ich verwende, modifiziert aus dem Code

  

Funktion 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; 
     

}

ein PHP erstellen und in Ihrer localhost Luhn (xxxxxxxx) laufen zu bestätigen.

BAD

Ich kann buchstäblich nicht glauben, wie viele miese Implementierungen gibt es da draußen.

  

IDAutomation hat eine NET-Assembly mit einer MOD10 () -Funktion schaffen, aber es scheint einfach nicht zu funktionieren. In Reflektor ist der Code viel zu lang für das, was es ohnehin zu tun angenommen hat.


BAD

dieses Chaos einer Seite , die tatsächlich gerade aus verbunden ist Wikipedia (!) für Javascript hat mehrere Verifikations Implementierungen, die nicht einmal den gleichen Wert zurück, wenn ich jeden Anruf.


GOOD

Die Seite verlinkt sind, um von Wikipedias Luhn hat einen Javascript-Encoder das scheint zu funktionieren:

// 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());​

GOOD

Das sehr nützlich EE4253 Seite verifiziert die Prüfziffer und zeigt auch die vollständige Berechnung und Erklärung.


GOOD

Ich brauchte C # -Code und am Ende mit diesen Code Projektcode :

// 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;
        }

GOOD

Der Validierungscode in C # scheint, wenn auch ein wenig unhandlich zu arbeiten. Ich habe es nur die oben zu überprüfen war korrekt.

Es gibt jetzt eine GitHub Repo basiert auf der ursprünglichen Frage / Antwort. Siehe

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

Es ist auch erhältlich bei packagist

Dies ist eine Funktion, die Ihnen helfen könnte, es ist kurz und es funktioniert gut.

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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top