Luhn checksum'ları oluşturuluyor

4 Cevap php

Luhn sağlama doğrularken, ancak bunları üretmek için çok az için uygulamaların çok sayıda bulunmaktadır. Ben ancak benim testlerde o adamcağız olmak için ortaya koymuştur this one geldim ve ben delta değişken, arkasındaki mantığı anlamıyorum.

Ben sözde Luhn sağlama oluşturulan ama henüz anlamış değil nedense oluşturulan sağlama zaman geçersiz yarısı bu işlevi yaptık.

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

Bazı örnekler:

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

Ben oluşturulan toplamlarını against this page, burada yanlış ne yapıyorum doğrulayarak ediyorum?


For future reference, here is the working function.

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

Bu amaçla gerek yok, ve doğrulamak için çünkü ben $ paritesi değişken düştü:

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

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

    return false;
}

4 Cevap

Edit: Üzgünüm, zaten, sadece yanlış hangi rakam için hangi faktör tespit etmişti neredeyse tüm benim cevabım vardı şimdi biliyoruz.

Benim tüm cevap şimdi bu tek cümle ile özetlenebilir:

Sen sayısının uzunluğuna bağlı olarak 2 ile yanlış basamak çoğalıyorlar, faktör tersine var.


Wikipedia article on the Luhn algorithm bir göz atın.

Lütfen sağlama zamanı geçersiz yarısı nedeni kontrolleri ile, yarım saat numaranız basamak garip bir numarası vardır, ve o zaman yanlış rakam çift olmasıdır.

37283 için, sağdan sayarken, sen sayı bu dizi olsun:

  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

Algoritma, orijinal sayı tek basamak özetlemek için gerekir, ve bu "sağ her iki basamaklı" ürününün tek tek basamaklı.

Yani sağdan, size 20 verir, + 2 + (1 + 4) + 3 3 + (1 + 6) Özetle.

Numarası 20 yapan bir sıfır ile uçları ile sona varsa, sayı geçerlidir.

Şimdi, soru sağlama oluşturmak için nasıl bilmek isteyen ima, iyi, kolay, aşağıdakileri yapın:

  1. Ekstra bir sıfır Tack, böylece sayı xyxyxyxy0 için xyxyxyxy gider
  2. Yeni sayı için Luhn sağlama toplamını hesaplamak
  3. Toplamını alın, 10 modüllü, yani 0-10 tek haneli olsun
  4. Rakam 0 ise, o zaman tebrikler, sizin sağlama basamaklı bir sıfır oldu
  5. Aksi takdirde, bunun yerine sıfır, son basamak için gerekenleri almak için 10 haneli hesaplamak

Örnek: Sayı 12345

  1. Bir sıfır Tack: 123450
  2. Sonuçları 123450 için Luhn sağlama, hesaplamak

    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) toplamını alın, size 5 verir, 10 modüllü

  4. Basamak (5), sıfır değildir
  5. Size 5 verir, 10-5 hesaplamak, son rakam 5 olmalıdır.

Bu nedenle sonuç 123.455 olan.

your php is buggy, it leads into an infinite loop. This is the working version that I'm using, modified from your code

fonksiyonu Luhn ($ sayı) {

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

}

Bir php oluşturmak ve onaylamak için localhost Luhn (xxxxxxxx) çalıştırın.

BAD

Ben tam anlamıyla orada kaç köhne uygulamaları inanamıyorum.

IDAutomation oluşturmak için .NET assembly with a MOD10() function var ama sadece çalışmak için görünmüyor. Yansıtıcı olarak kod zaten yapıyor olması gerekiyordu ne için yol çok uzun.


BAD

This mess of a page ki aslında şu anda Javascript için Wikipedia (!) Den bağlantılı ben her birini aramak bile aynı değeri döndüren birkaç doğrulama uygulamaları vardır.


GOOD

page linked to from Wikipedia's Luhn page iş gibi görünüyor Javascript encoder var:

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

Bu very useful EE4253 sayfa check-haneli doğrular ve aynı zamanda tam bir hesaplama ve açıklamasını gösterir.


GOOD

Ben C # kodu gerekli ve bu kullanarak sona erdi code project code:

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

Bu validation code in C# iş gibi görünüyor, biraz hantal eğer. Ben sadece yukarıdaki kontrol etmek için kullanılan doğru idi.

Özgün soru / cevap dayalı bir github repo şimdi var. Görmek

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

Bu packagist da mevcuttur bulunuyor