This post will cover the encoding scheme defined by the ABA for magnetic stripe cards. This format is the de facto standard for track 2 of magnetic stripe cards.
Character Encoding Overview
- Each character is five bits in length. Four bits for the character itself, and an odd parity bit.
- The character set includes 16 ASCII symbols, ranging from 0x30 – 0x3f on the ASCII table. These are numerical digits 0-9 and the characters : ; < = > ?
- Encoded characters are offset from ASCII by decimal 48 (thus, the numeric digit 0 is stored as 0, and a value of 48 must be added to get the ASCII character 0).
- Values are stored in binary in Least Significant Bit (LSB) order. E.g., the number 4 is stored as 001 and not 100.
I’ll go over a few quick examples of this.
The start sentinel is the semi-colon character. This is ASCII value 59, but we subtract 48 from this. We then have decimal 11, and in LSB binary: 1101. We then apply the parity bit to the end, which is 0 here as there is an odd number of 1s. Thus, the encoded character is 11010.
Another example, the number 5. This is ASCII 53, but becomes the number 5 once 48 is subtracted. In LSB binary, it is 1010. There is an even number of 1s, so the parity bit is 1. The encoded character is 10101.
- Always starts with a semi-colon, the “start sentinel”, to indicate beginning of data.
- Always ends with a question mark, the “end sentinel”, to indicate end of data.
- The equal sign is used as a field separator. Traditionally this is put between an account number an expiration date. Some cards will contain no field separators, others may contain multiple.
- Only numeric digits should be used to store data — the remaining characters, : < >, are for hardware control purposes.
- A 5 bit Longitudinal Redundancy Check (LRC) character always follows the end sentinel. It uses an even parity bit scheme, as opposed to the odd parity used for characters. Its fifth bit is an odd parity of the other 4 bits, and not an LRC parity bit.
- A total of 40 characters can be stored, including start/end sentinels and field separators.
Longitudinal Redundancy Calculation
The LRC is calculated by looking at all the other encoded characters on the card and calculating an even parity bit.
I’ll go over an example here. Let’s assume we have the string ;12=34? as data to encode:
11010 ; 10000 1 01000 2 10110 = 11001 3 00100 4 11111 ? 10110 LRC
Just do addition down each column. If the total is odd, then the LRC parity bit for that position is 1. If the total is even, it’s a 0. The fifth bit of the LRC is an odd parity of the first four bits. In this case, the LRC is 1011, which is an odd number of bits, making the encoded LRC 10110. The fully encoded stream is then:
Next I’ll do a quick overview of how data is commonly ordered on a card:
Common Data Ordering
- Start Sentinel
- Primary Account Number (PAN). Up to 19 digits in length. Overflow can be stored in the custom data section.
- Field Separator
- Expiration date in the format YYMM
- Custom data. Length is up to the remaining space.
- End Separator
This format is found on many cards, such as credit cards. Odds are if you have a magnetic stripe card with an identification number and expiration date, it follows this pattern.
Not all cards will follow this, refer to the data formatting section above for some rules that should be consistently followed.