Kreditkartennummern in Java testen

Sind Kreditkartennummern korrekt aufgebaut? Wie lassen sich sich Kreditkartennummern generieren?

E-Commerce-Lösungen sind im Internet mittlerweile häufig anzutreffen. Lassen sich für kleine Beträge Sonderlösungen finden, werden für größere Beträge immer noch Kreditkarten verwendet. Grund genug für uns Java-Programmierer, die Nummern der Karten zu testen, um zu überprüfen, ob uns nicht ein Anwender täuschen wollte.

Die Nummer einer Kreditkarte setzt sich nicht willkürlich zusammen. Die Nummern von Karten eines bestimmten Herstellers bestehen aus einer festen Anzahl von meistens 14 bis 16 Ziffern. Als Kennung für einen Hersteller (Visa (Veni, Vidi, VISA: I came, I saw, I did a little shopping.) , MasterCard, American Express) ist jeder Nummer eine zusätzliche Kennung von einer bis vier Ziffern vorangestellt. Die Ziffern der Kartennummer werden durch mathematische Verfahren überprüft. Wir wollen eines dieser Verfahren auch kennen lernen; den so genannten Luhn-Algorithmus. Dieser Algorithmus testet die Korrektheit des Aufbaus einer Nummernfolge. Die letzte Ziffer ist oft eine berechnete Checksummen-Ziffer.

Die folgende Tabelle gibt eine Übersicht über einige Kartenhersteller. Sie führt die Kennung, die Länge der Kartennummer und ein gültiges Beispiel auf:

Hersteller

Anfang

Gesamtlänge

Beispiel

Visa

4

13,16

4111 1111 1111 1111

Master

51,52,53,54,55

16

5500 0000 0000 0004

Diner’s Club11

30,36,38

14

3000 0000 0000 04

American Express12

34,37

15

3400 0000 0000 009

Discover

6011

16

6011 0000 0000 0004

en Route

2014,21

15

2014 0000 0000 009

JCB

3088,3096,3112,3158,3337,3528

16

3088 0000 0000 0009

Neben den Herstellernummern sind auch folgende Nummern von den ausgebenden Ban­ken im Umlauf: Manufacturers Hanover Trust (1033), Citibank (1035), Chemical Bank (1263), Chase Manhattan (1665), Bank of America (4024), Citicorp (4128), New Era Bank (4209), HHBC (4302), Imperial Savings (4310), MBNA (4313), California Federal (4317), Wells Fargo (5282), Citibank (5424), Wells Fargo (5410), Bank of New York (5432), MBNA (6017). Carte Blanche und Diner’s Club haben die gleichen Nummern.

Einen Abend im Februar 1950 vergaß Frank MacNamara seine Brieftasche. Er kam auf die Idee, eine Kredit­karte aus Karton anzubieten. Mit seinen Freunden gründete er am 28.2.1950 den Diner’s Club, der im Grün­derjahr mehr als 10.000 Mitglieder und 1.000 Vertragspartner hatte. So war die erste Kreditkarte geboren. Im Jahre 1958 entschloss sich das internationale Transport-, Reise-, und Finanzierungsunternehmen American Express, eine eigene Karte herauszugeben.

Die Überprüfung mit dem Luhn-Algorithmus

Der Luhn-Algorithmus (auch modulus 10 oder mod 10-Algorithmus genannt) basiert auf dem ANSI-Vorschlag X4.13. Er wurde Ende 1960 von einer Gruppe Mathematiker ausgearbeitet und veröffentlicht. Danach nutzten Kreditkartenhersteller dieses Verfahren zur Prüfung der Kreditkartennummern. Auch die Versichertennummer in Kanada, die Canadian Social Insurance Number (CSIN), wird über das Luhn-Verfahren geprüft.

Der Algorithmus testet, ob die letzte Ziffer der Kreditkartennummer korrekt zu den angegebenen Zahlen passt. Die Testziffer wird von allen Ziffern außer der letzten Ziffer berechnet und anschließend mit der angegebenen Testziffer verglichen. Stimmt sie überein, ist die Karte seitens der Prüfnummer in Ordnung. Wir wollen das Verfahren hier nicht näher vertiefen, sondern einfach den Algorithmus angeben:

class LuhnTest
{
  static boolean luhnTest( String s )
  {
    int len = s.length();

    int digits[] = new int[len];

    for ( int i = 0; i < len; i++ )
    {
      try {
        digits[i] = Integer.parseInt( s.substring(i,i+1) );
      }
      catch ( NumberFormatException e ) {
        System.err.println( e );
        return false;
      }
    }

    int sum=0;

    while ( len > 0 )
    {
      sum += digits[len-1];
      len--;

      if ( len > 0 )
      {
        int digit = 2*digits[len-1];
        sum += ( digit>9) ? digit-9 : digit;

        len--;
      }
    }

    return ( sum%10 == 0 );
  }


  static boolean isVisa( String s )
  {
    if ( ( (s.length() == 16) || (s.length() == 13) ) &&
          (s.charAt(0) == '4') )
      return luhnTest( s );

    return false;
  }

  public static void main( String args[] )
  {
    System.out.println( luhnTest( "4111111111111111" ) );
    System.out.println( luhnTest( "5500000000000004" ) );
    System.out.println( luhnTest( "340000000000009" ) );
    System.out.println( luhnTest( "30000000000004" ) );
    System.out.println( luhnTest( "601100000000000" ) );
    System.out.println( luhnTest( "201400000000009" ) );
    System.out.println( luhnTest( "3088000000000009" ) );
    System.out.println( luhnTest( "9238475098787444" ) );

    System.out.println( isVisa( "4111111111111111" ) );
    System.out.println( isVisa( "5500000000000004" ) );


    // Böse: Visa-Nummer generieren

    char[] c = "4123456789123456".toCharArray();

    while ( !isVisa(new String(c)) )
      c[(int)(Math.random()*c.length-1)+1] = (char)('0'+Math.random()*9.9);

    System.out.println( c );
  }
}

Im Quelltext ist eine zusätzliche Methode eingebaut, die testet, ob die Karte von Visa ist. Dazu müssen wir nur überprüfen, ob die erste Ziffer eine 4 und die gesamte Zahl nach dem Luhn-Verfahren gültig ist. Andere Tests sind genauso einfach durchzuführen. Eine mögliche Erweiterung wäre, die Methode fehlertoleranter zu gestalten, indem Trennzeichen herausgefiltert werden. Dies und die Implementierung der übrigen Tests überlasse ich als Übung den Lesern.

Wir beginnen mit einer vorgegebenen, unsinnigen Kartennummer, deren erste Stelle "4" ist, wie für eine Visa-Karte erforderlich. Anschließend ändern wir in einer Schleife eine zufällig ausgewählte Stelle der Kartennummer (außer der ersten) in eine ebenfalls zufällig bestimmte Ziffer aus dem Bereich "0" bis "9". Das wiederholen wir so lange, bis die abgewandelte Zahl irgendwann passt.

Beispiel Mit diesen Methoden ist es natürlich leicht möglich, Nummern zu erzeugen. Betrachten wir Folgendes:

char c[] = "4123456789123456".toCharArray();
while ( !isVisa(new String(c)) )
  c[(int)(Math.random()*c.length-1)+1] = (char)('0'+Math.random()*9.9);
System.out.println( c );

Ähnliche Beiträge

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert