ISO 8583 Parser
在线速查

进制与 BCD 转换器

十六进制、十进制、二进制、压缩十进制(Packed BCD)四种表示互转。改任意一格,其余三格实时联动;全程大整数运算,12 位以上的金额也不丢精度。

符号 nibble 按 IBM 压缩十进制惯例:编码时正数收 C、负数收 D、无符号用 F解码A/C/E/F 判正,B/D 判负。奇数位数字自动在最前面补一个 0 nibble 对齐到整字节。负数在十进制 / Hex / 二进制框用负号表示。

压缩十进制(Packed BCD)是什么

压缩十进制把每个十进制数字塞进 4 个 bit(一个 nibble),一个字节存两位数字:1234 存成 0x12 0x34,字节内容和你肉眼看到的数字长得一模一样,这是它最好认的特征。相比每位数字占一整个字节的 ASCII(123431 32 33 34 四个字节),空间直接省一半。

大机清算文件里它无处不在:批量文件动辄几百万条记录,金额、卡号、日期这些纯数字段全用 BCD 存,文件体积和传输时间都减半;而且它和 COBOL 的 COMP-3(packed decimal)字段一一对应,大机程序不需要任何转换就能直接做十进制运算。ISO 8583 报文用 BCD 编码时,DE4 金额这类 n12 域打包成 6 个字节,就是同一套东西。

符号 nibble 对照表

有符号的压缩十进制把符号放在最后一个 nibble(最低半字节),前面全是数字。按 IBM 惯例:

符号 nibble含义说明
0xC编码时正数的标准写法(credit)
0xD编码时负数的标准写法(debit)
0xF无符号(按正处理)无符号字段的写法,COBOL 里 PIC 9 COMP-3(不带 S)就长这样
0xA0xE解码时要认,编码时不用
0xB解码时要认,编码时不用

一句话记:编码只出 C / D / F,解码要认全 A、C、E、F 为正,B、D 为负。上面工具的三种模式分别对应:ISO 8583 金额域那种不带符号位的纯数字 BCD、C/D 结尾的有符号 COMP-3、F 结尾的无符号 COMP-3。

手工核对一个完整例子

1234 编成有符号压缩十进制,逐步来:

  1. 数字拆成 nibble:1、2、3、4,共 4 个,再加 1 个符号 nibble,总共 5 个——是奇数,凑不成整字节。
  2. 在最前面补一个 0:变成 0、1、2、3、4 加符号,共 6 个 nibble,正好 3 个字节。
  3. 正数符号用 C,排开:0 1 | 2 3 | 4 C
  4. 最终字节:0x01 0x23 0x4C

反过来验算:读到 01 23 4C,最后一个 nibble 是 C(正),其余 nibble 依次是 0 1 2 3 4,去掉前导零就是 1234。换成 -1234,只有最后一个 nibble 变成 D0x01 0x23 0x4D。你可以把这几个值丢进上面的工具对一遍。

顺带说金额:ISO 8583 的金额域存的是最小货币单位的整数1234.56 美元存 123456),小数点位置由货币的小数位决定,本工具只做整数值的表示转换。小数位怎么查、怎么换算,见金额为什么没有小数点货币码与小数位查询

常见坑

补零补错边(0x0C vs 0xC0)。奇数位补齐的那个 0 永远补在最前面,符号 nibble 永远在最后。把 5 编成 0xC5(符号跑到高位)或把补位放到尾部,整串数字全部错位,而且往往还能"解出来"一个看似合理的错值,极难肉眼发现。

F 当成数字 15 读。无符号 BCD 的尾 nibble F 是符号占位,不是数字。123F123,而通用的 hex 转十进制会把整串当 0x123F = 4671——这就是 BCD 字段不能直接丢进普通进制转换的原因。

zoned decimal 和 packed decimal 混淆。zoned(区位十进制,COBOL 里的 DISPLAY)是每个字节存一位数字,高 nibble 是区位 F(EBCDIC 下 F1 F2 F3 就是字符 123),符号叠在最后一个字节的高 nibble 上;packed 才是一字节两位。拿 packed 的解法去读 zoned,长度直接差一倍。

奇偶位数没对齐。发送方按奇数位补了前导 0、接收方按原始位数截取(或反过来),后面所有 nibble 集体移位。遇到解出来"每一位都差一格"的 BCD 字段,先查两边对位数和补齐的约定是否一致。