Thema: Delphi Kreditkarten Check

Einzelnen Beitrag anzeigen

Benutzerbild von Sanchez
Sanchez

Registriert seit: 24. Apr 2003
Ort: Neumarkt Stmk
892 Beiträge
 
Delphi XE6 Enterprise
 
#1

Kreditkarten Check

  Alt 20. Aug 2003, 09:41
Dies Unit überprüft Kreditkartennummer aufgrund des Präfixes (Kartentyp), Nummernlänge und Checksumme:

Delphi-Quellcode:
unit Creditc;

{ Überprüft eine Kreditkartennummer anhand Länge, Kartentyp und Checksumme
   
   function IsValidCreditCardNumber( CardNumber: String; var MessageText: String ): Boolean;
   
   return true  --> Nummer OK, Messagetext übergibt den Kartentyp
   return false --> Nummer ungültig, Messagetext erklärt genaueres
}


interface

uses SysUtils;

function IsValidCreditCardNumber( CardNumber: String; var MessageText: String ): Boolean;


implementation

const
  CardPrefixes: array[ 1..19 ] of string =
                ( '2014', '2149', '300', '301', '302',
                  '303', '304', '305', '34', '36', '37',
                  '38', '4', '51', '52', '53', '54', '55', '6011' );

  CardTypes: array[ 1..19 ] of String =
             ( 'enRoute',
               'enRoute',
               'Diner Club/Carte Blanche',
               'Diner Club/Carte Blanche',
               'Diner Club/Carte Blanche',
               'Diner Club/Carte Blanche',
               'Diner Club/Carte Blanche',
               'Diner Club/Carte Blanche',
               'American Express',
               'Diner Club/Carte Blanche',
               'American Express',
               'Diner Club/Carte Blanche',
               'Visa',
               'MasterCard',
               'MasterCard',
               'MasterCard',
               'MasterCard',
               'MasterCard',
               'Discover' );


function RemoveChar(const Input: String; DeletedChar: Char): String; //wirft DeletedChar aus dem String
var
  i: integer;
begin
  result := Input;
  for i := Length( Result ) downto 1 do
    if Result[ i ] = DeletedChar then Delete( Result, i, 1 );
end;

function ShiftMask( Input: Integer ): Integer;
begin
  //Wrapper für shift left Operation
  result := ( 1 shl ( Input - 12 ) );
end;

//Checksumme berechnen
function ConfirmChecksum( CardNumber: String ): Boolean;
var
  CheckSum: Integer; //Checksumme
  Flag: Boolean;
  i: integer;
  Number: integer; //immer eine Ziffer
begin
  i := Length( CardNumber );
  CheckSum := 0;
  Number := 0;
  Flag := false;

  while ( i >= 1 ) do
  begin
    { get the current digit } 
    Number := StrToInt(Copy( CardNumber, i, 1 ));

    if ( Flag ) then
    begin
      Number := Number * 2;
      if ( Number >= 10 ) then Number := Number - 9;
    end;
    CheckSum := CheckSum + Number;
    Flag := not( Flag );
    i := i - 1;
  end;
  result := ( ( CheckSum mod 10 ) = 0 );
end;

function GetMask( CardName: String ): Integer;
begin
  result := 0;

  if ( CardName = 'MasterCard' ) then result := ShiftMask( 16 );
  if ( CardName = 'Visa' ) then result := ( ShiftMask( 13 ) or ShiftMask( 16 ) );
  if ( CardName = 'American Express' ) then result := ShiftMask( 15 );
  if ( CardName = 'Diner Club/Carte Blanche' ) then result := ShiftMask( 14 );
  if ( CardName = 'Discover' ) then result := ShiftMask( 16 );
  if ( CardName = 'enRoute' ) then result := ShiftMask( 15 );
end;

function IsValidCreditCardNumber( CardNumber: String; var MessageText: String ): Boolean;
var
  StrippedNumber: String; //Nummer ohne Spezialzeichen
  i: integer;
  TheMask: integer;
  FoundIt: Boolean; //Kartentyp gefunden
  CardName: String; //Kartenname
  PerformChecksum: Boolean; //enroute-Karte hat keine Checksumme
begin
  // Leerzeichen und - rauswerfen
  StrippedNumber := RemoveChar( CardNumber, ' ' );
  StrippedNumber := RemoveChar( StrippedNumber, '-' );

  // Wenn der String länge 0 hat, ist auch OK (Warum auch immer)
  if ( StrippedNumber = '' ) then begin
    result := true;
  exit;
end;


  MessageText := '';
  result := true;
  FoundIt := false;

  //ungültige Zeichen herausfischen
  for i := 1 to Length( StrippedNumber ) do
  begin
    case StrippedNumber[ i ] of
      '0'..'9': FoundIt := FoundIt; //hier machen wir nix
      else
        MessageText := 'ungültige Zeichen in Kartennummer';
        result := false;
        exit;
    end;
  end;

  //Kartentyp herausfinden
  for i := 1 to 19 do
  begin
    if ( Pos( CardPrefixes[ i ], StrippedNumber ) = 1 ) then
    begin
      //gefunden
      FoundIt := true;
      CardName := CardTypes[ i ];
      TheMask := GetMask( CardName );
      break;
    end;
  end;

  //Wenn kein Kartentyp gefunden, hat die Nummer schon verloren
  if ( not FoundIt ) then
  begin
    CardName := 'Kartentyp nicht bekannt';
    TheMask := 0;
    MessageText := 'Kartentyp nicht bekannt';
    result := false;
    exit;
  end;

  //allgemeine Längenüberprüfung
  if ( ( Length( StrippedNumber ) > 28 ) and result ) then
  begin
    MessageText := 'Nummer ist zu lang';
    result := false;
    exit;
  end;

  //genaue Längenprüfung
  if ( ( Length( StrippedNumber ) < 12 ) or
     ( ( shiftmask( length( strippednumber ) ) and themask ) = 0 ) ) then
  begin
    messagetext := 'ungültige Nummernlänge';
    result := false;
    exit;
  end;

  //Checksumme überprüfen
  if ( cardname = 'enroute' ) then
    performchecksum := false
  else
    performchecksum := true;

  if ( performchecksum and ( not confirmchecksum( strippednumber ) ) ) then
  begin
    messagetext := 'ungültige Checksumme';
    result := false;
    exit;
  end;

   //Wenn Result immer noch true ist, ist die Nummer gültig
   if ( result ) then
     messagetext := cardname;
end;

end.
grüße, daniel

[edit=Matze]Code formatiert. Mfg, Matze[/edit]
Daniel
  Mit Zitat antworten Zitat