Search code examples
regexcredit-card

Regular Expression for Credit Card Track Data


Are there any known regular expressions out there to validate credit card track 1 and track 2 data?

EDIT:

From Wikipedia:

The information on track 1 on financial cards is contained in several formats: A, which is reserved for proprietary use of the card issuer, B, which is described below, C-M, which are reserved for use by ANSI Subcommittee X3B10 and N-Z, which are available for use by individual card issuers:

Track 1, Format B:

  • Start sentinel — one character (generally '%')
  • Format code="B" — one character (alpha only)
  • Primary account number (PAN) — up to 19 characters. Usually, but not always, matches the credit card number printed on the front of the card.
  • Field Separator — one character (generally '^')
  • Name — two to 26 characters
  • Field Separator — one character (generally '^')
  • Expiration date — four characters in the form YYMM.
  • Service code — three characters
  • Discretionary data — may include Pin Verification Key Indicator (PVKI, 1 character), PIN Verification Value (PVV, 4 characters), Card Verification Value or Card Verification Code (CVV or CVK, 3 characters)
  • End sentinel — one character (generally '?')
  • Longitudinal redundancy check (LRC) — it is one character and a validity character calculated from other data on the track. It should be noted that most reader devices do not return this value when the card is swiped to the presentation layer, and use it only to verify the input internally to the reader.

Track 2: This format was developed by the banking industry (ABA). This track is written with a 5-bit scheme (4 data bits + 1 parity), which allows for sixteen possible characters, which are the numbers 0-9, plus the six characters : ; < = > ? . The selection of six punctuation symbols may seem odd, but in fact the sixteen codes simply map to the ASCII range 0x30 through 0x3f, which defines ten digit characters plus those six symbols. The data format is as follows:

  • Start sentinel — one character (generally ';')
  • Primary account number (PAN) — up to 19 characters. Usually, but not always, matches the credit card number printed on the front of the card.
  • Separator — one char (generally '=')
  • Expiration date — four characters in the form YYMM.
  • Service code — three characters
  • Discretionary data — as in track one
  • End sentinel — one character (generally '?')
  • Longitudinal redundancy check (LRC) — it is one character and a validity character calculated from other data on the track. It should be noted that most reader devices do not return this value when the card is swiped to the presentation layer, and use it only to verify the input internally to the reader.

Solution

  • I was about to post the same link on regular-expressions.info, for verifying the cc number part of the track.

    Now, comes the tricky part. Track data varies in format between card issuers and even card readers. For example the 'separator' characters aren't always the same. Same applies to the end 'sentinels'.

    Wikipedia gives a good overview: http://en.wikipedia.org/wiki/Magnetic_stripe_card

    With track2, the card number is followed by an '=' (or occasionally a 'D'). Then you have expiry date as MMDD. After that, Track2 has 'discretionary data', which could be anything.

    I wouldn't worry too much after this point. If it's track data, you'll be pretty sure by now. I guess it depends on what you are aiming to do with the data.

    Anyway, for Track2 you could do a lot worse than adding [=D][0-9]{4} instead of the $ at the end of the cc regex:

    ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})[=D][0-9]{4}
    

    For track1, you could do something similar ... Track1 contains more variable data, so can be a touch more complicated.

    Good luck!