ISO 8583 Parser
Free ยท Reference ยท ~9 min read ยท Updated 2026-08-13
encoding ยท iso 8583

ASCII, Packed BCD and EBCDIC: How the Same Value Becomes Bytes

The MTI 0200 leaves for the wire as 30 32 30 30 on an ASCII link, as 02 00 packed BCD, and as F0 F2 F0 F0 EBCDIC. Same four characters, 4, 2 and 4 bytes โ€” and every field boundary in the message moves with that count. Below: the three side by side, the packed BCD rules, and the full EBCDIC (CP500) to ASCII table.

One value, three encodings

Three values that appear in almost every authorization message, each written out the three ways it can travel. Watch the byte counts, not just the byte values.

MTI 0200 โ€” 4 digits:

RepresentationBytes on the wireLength
ASCII30 32 30 304 bytes
Packed BCD02 002 bytes
EBCDIC (CP500)F0 F2 F0 F04 bytes

DE4 amount 000000005000 โ€” n 12, $50.00 in minor units:

RepresentationBytes on the wireLength
ASCII30 30 30 30 30 30 30 30 35 30 30 3012 bytes
Packed BCD00 00 00 00 50 006 bytes
EBCDIC (CP500)F0 F0 F0 F0 F0 F0 F0 F0 F5 F0 F0 F012 bytes

DE2 PAN 5413330089010001 โ€” 16 digits:

RepresentationBytes on the wireLength
ASCII35 34 31 33 33 33 30 30 38 39 30 31 30 30 30 3116 bytes
Packed BCD54 13 33 00 89 01 00 018 bytes
EBCDIC (CP500)F5 F4 F1 F3 F3 F3 F0 F0 F8 F9 F0 F1 F0 F0 F0 F116 bytes

The length difference is the whole story. A parser that expects ASCII and receives BCD consumes twice as many characters as exist; one that expects BCD and receives ASCII stops halfway through the field. Either way every boundary after the first mismatched field is wrong โ€” which is why encoding sits at step two of the parse-failure check order, right after framing. To see any of these byte strings decoded live, paste them into the hex viewer: it renders the same bytes as ASCII and EBCDIC in parallel columns.

One thing the three tables quietly demonstrate: a field format like n 12 tells you the field holds twelve digits โ€” it does not tell you whether those digits occupy 12 bytes or 6. Format notation and encoding are two independent agreements, and the notation guide covers the first one only. The second is settled per link, in the interface specification.

Packed BCD: two digits per byte

Packed BCD (binary-coded decimal) stores one decimal digit in each 4-bit nibble, so a byte carries two digits โ€” high nibble first. 0200 becomes 02 00; the hex dump of a BCD field reads exactly like the number itself, which is both its charm and the easiest way to recognise it.

That halving is the reason BCD exists on payment links at all: an n 12 amount drops from 12 bytes to 6, a 16-digit PAN from 16 to 8. Across millions of messages and batch records the savings were worth caring about when these interfaces were designed, and the convention outlived the constraint. The hex / decimal / BCD converter does the packing and unpacking interactively, including the byte counts.

Two properties follow from the nibble layout:

Sign nibbles: on some links, amount-class BCD fields carry a sign nibble alongside the digits (mainframe packed-decimal style). Which nibble values mean what varies by implementation โ€” take the assignment from your endpoint's specification rather than any general table.

EBCDIC (CP500) to ASCII conversion table

EBCDIC is a family of code pages, not one encoding. CP037, CP500, CP1047 and dozens of national variants agree on digits, letters and most punctuation but disagree at a handful of positions โ€” square brackets, the exclamation mark, the vertical bar and a few other symbols sit at different code points depending on the page. The tables below are CP500 (International), the same code page the hex viewer decodes with. If your counterparty declares a different page, the rows marked "varies" are exactly the ones to re-check against their specification.

Digits 0โ€“9

The rows you will use most. An EBCDIC digit is F plus the digit in the low nibble โ€” which is why a numeric field dumped from an EBCDIC file is a wall of F0โ€“F9, and why stripping the high nibble of each byte recovers the packed-BCD form of the same number.

EBCDIC (CP500)CharacterASCII
F0030
F1131
F2232
F3333
F4434
F5535
F6636
F7737
F8838
F9939

Uppercase Aโ€“Z

Unlike ASCII, the EBCDIC alphabet is not contiguous: it runs in three blocks, C1โ€“C9 (Aโ€“I), D1โ€“D9 (Jโ€“R) and E2โ€“E9 (Sโ€“Z), with unrelated code points in the gaps. Any code that range-checks "between A and Z" byte-wise breaks on EBCDIC data.

EBCDIC (CP500)CharacterASCII
C1A41
C2B42
C3C43
C4D44
C5E45
C6F46
C7G47
C8H48
C9I49
D1J4A
D2K4B
D3L4C
D4M4D
D5N4E
D6O4F
D7P50
D8Q51
D9R52
E2S53
E3T54
E4U55
E5V56
E6W57
E7X58
E8Y59
E9Z5A

Lowercase aโ€“z

The same three-block pattern, one bit lower: 81โ€“89, 91โ€“99, A2โ€“A9. Note that every lowercase letter has the high bit set โ€” bytes that would be outside printable ASCII entirely.

EBCDIC (CP500)CharacterASCII
81a61
82b62
83c63
84d64
85e65
86f66
87g67
88h68
89i69
91j6A
92k6B
93l6C
94m6D
95n6E
96o6F
97p70
98q71
99r72
A2s73
A3t74
A4u75
A5v76
A6w77
A7x78
A8y79
A9z7A

Punctuation and symbols

Sorted by EBCDIC code point. The "varies" rows are the classic cross-code-page traps: those characters sit at different positions in CP037 and CP1047, so a file decoded with the wrong page comes out with brackets and bars swapped for other symbols while everything else looks fine.

EBCDIC (CP500)CharacterASCIINotes
40space20EBCDIC padding runs are 40, not 20
4A[5Bvaries by code page
4B.2E
4C<3C
4D(28
4E+2B
4F!21varies by code page
50&26
5A]5Dvaries by code page
5B$24
5C*2A
5D)29
5E;3B
5F^5Evaries by code page
60-2D
61/2F
6B,2C
6C%25
6D_5F
6E>3E
6F?3F
79`60
7A:3A
7B#23
7C@4040 is @ in ASCII but space in EBCDIC
7D'27
7E=3D
7F"22
A1~7E
BB|7Cvaries by code page
C0{7B
D0}7D
E0\5C

Control characters and the unassigned positions are deliberately not listed โ€” they never appear in message text on purpose. For any byte outside these tables, paste the hex into the hex viewer and read it off the dump: it decodes all 256 positions, byte by byte.

Telling which encoding a dump is in

Start at byte zero. The MTI is the first field of every message, its value is one of a short list, and each encoding gives it away differently:

If the dump starts withโ€ฆIt reads asVerdict
30 31 / 30 32 / 30 38โ€ฆ01โ€“08xx as ASCII digitsASCII
01 00 / 02 00 / 08 00โ€ฆthe MTI literally, two bytesPacked BCD
F0 F1 / F0 F2 / F0 F8โ€ฆ01โ€“08xx as EBCDIC digitsEBCDIC

Past the first bytes, the statistics of the dump usually settle it on sight:

When the statistics are ambiguous โ€” short dump, mixed per-field encodings โ€” decode it all three ways and keep the reading that yields a plausible MTI and a bitmap whose bits match the fields you can see. Three attempts in the hex viewer (ASCII and EBCDIC in one paste) plus the BCD converter take about two minutes, which is reliably faster than locating the encoding clause in an interface document. That try-all-three step is exactly where the parse-failure check order puts encoding: after framing, before anything field-level.

Where you actually meet each one

Batch clearing leans EBCDIC. Mastercard IPM (T112) clearing files are the canonical case: mainframe-era platforms, mainframe-native character set, unchanged since. If a "corrupted" file turns readable in the EBCDIC column of a hex dump, that is what you are holding โ€” and the IPM file parser decodes those records field by field.

Online authorization links are most often ASCII, with packed BCD common on links that care about message size โ€” frequently per field, numeric fields packed and text fields not. Which combination your link uses is a property of that link's interface specification, not of the card network in general, so take it from the spec โ€” or determine it empirically as above, which is usually faster.

The annotated sample messages are written in the friendliest form of all โ€” plain ASCII text โ€” precisely so you can paste them straight into the parser and watch a full decode without fighting byte-level encoding first. That page's encoding notes cover how the same samples change shape on a packed link.


๐Ÿ‘‰ Holding a real dump right now? Paste it into the hex viewer to see ASCII and EBCDIC side by side, then hand the winner to the parser for the field-by-field breakdown.

Read next