ISO 8583 Parser
免费 · 实操教程 · 约 9 分钟 · 最后更新 2026-08-12

ISO 8583 位图手算指南:十六进制与域号互转

位图是每条 ISO 8583 报文的目录:8 或 16 个字节,宣告后面跟着哪些数据域。读完这页,你拿一张纸就能把任何一条十六进制位图拆成域号清单,也能反过来把一串域号拼回精确的十六进制——全程只需要查下面那张「十六进制 → 4 位二进制」的小表。

三条规则

这页所有内容都从三个事实推出来:

  1. 一个十六进制字符 = 4 位二进制。主位图是 16 个十六进制字符 = 64 位 = 8 字节。
  2. 位的编号从 1 到 64,从左往右数。不是 0 到 63。写程序的人习惯性从 0 数,得到的域号清单会整体错一位——这是位图上最常见的一个错。
  3. 第 N 位为 1,表示数据域 N 存在——唯一的例外是第 1 位:它不代表任何数据域,而是宣告后面还跟着第二张位图

把这张对照表放在手边,整个手算过程只需要查它:

十六进制二进制十六进制二进制
0000081000
1000191001
20010A1010
30011B1011
40100C1100
50101D1101
60110E1110
70111F1111

十六进制 → 域号,一步一步拆

拿一条真实位图从头走到尾:

7238400108C08000

步骤:

  1. 把 16 个十六进制字符横着写一排。
  2. 每个字符下面写出它的 4 位二进制(查上表)。
  3. 从左往右给每一位标号:1、2、3 …… 64。
  4. 标号处是 1 的,对应的域就存在。

一个省数数的捷径:第 k 个字符覆盖第 4(k−1)+1 到 4k 位。第 1 个字符管 1–4 位,第 2 个管 5–8 位,第 11 个管 41–44 位。完整拆解如下:

字符序号十六进制二进制覆盖位置位的域
1701111–42、3、4 (第 1 位 = 0 → 没有二级位图)
2200105–87
3300119–1211、12
48100013–1613
54010017–2018
60000021–24
70000025–28
81000129–3232
90000033–36
108100037–4037
11C110041–4441、42
120000045–48
138100049–5249
140000053–56
150000057–60
160000061–64

结果:域 2、3、4、7、11、12、13、18、32、37、41、42、49——典型授权报文的形状:卡号、处理码、金额、时间戳、STAN、时间日期、收单机构号、检索参考号、终端号、商户号、货币码。每个号码具体是什么,查域速查表;把同一串十六进制粘进位图计算器,它会把 64 位逐位画出来,跟你纸上的结果逐位对。

域号清单到手之后还有两件事要记住:数据域按域号从小到大排列,然后每个域各有各的长度规则(定长、LLVAR、LLLVAR)——那一层在读懂域格式记法里讲。

域号 → 十六进制,一个字节一个字节拼

反方向更好算的诀窍是:别想 64 个位,想 8 个字节、每个字节管 8 个域

字节12345678
管辖的域1–89–1617–2425–3233–4041–4849–5657–64

对任意域 N:字节序号 = ⌈N/8⌉字节内位置 = ((N−1) mod 8) + 1,从左数。每个位置有固定的十六进制权重——字节的值就是所有置位权重之和:

字节内位置12345678
权重(十六进制)8040201008040201

动手算一个——给定域 2、3、4、11、41,拼出位图:

字节管辖的域本字节里出现的位模式十六进制
11–82、3、40111000070 (40+20+10)
29–1611 → 位置 30010000020
317–240000000000
425–320000000000
533–400000000000
641–4841 → 位置 11000000080
749–560000000000
857–640000000000

把十六进制那列从上到下连起来读:

7020000000800000

验算两个不那么直观的域:域 11 → 字节 ⌈11/8⌉ = 2,位置 (11−1) mod 8 + 1 = 3,权重 20;域 41 → 字节 ⌈41/8⌉ = 6,位置 (41−1) mod 8 + 1 = 1,权重 80。在计算器的「域号 → 位图」输入框里敲 2,3,4,11,41,出来的正是这串十六进制。

二级位图:第 1 位到底是什么意思

第 1 位不是「DE1 存在」。第 1 位置位表示紧跟着第一张位图后面还有第二张 8 字节的位图(也叫扩展位图),覆盖域 65–128。DE1 本身就是二级位图——它永远不会作为数据域出现在解析结果里,所以任何一个正确的解码器都不会在输出里列出「域 1」。

二级位图的拆法和主位图完全一样,算完加 64:二级位图的位置 1 = 域 65,位置 6 = 域 70,位置 64 = 域 128。

下面是需要二级位图的最小真实报文——网络回声测试(0800),真实报文示例里逐字节拆过这一条:

8220000000000000 0400000000000000
部位十六进制二进制含义
主位图第 1 字符81000第 1 位置位 → 后面跟着二级位图
主位图第 2 字符20010第 7 位 → DE7(传输日期时间)
主位图第 3 字符20010第 11 位 → DE11(STAN)
二级位图第 1 字节0400000100位置 6 → 64 + 6 = DE70(网络管理码)

存在的域:7、11、70。就因为 DE70 超过了 64,这条只有三个域的小报文也必须背上 16 字节的位图。在解析器里打开完整的 0800 →

错误一:把数据当成二级位图来解

眼前摆着 32 个十六进制字符,不等于有 32 个字符的位图——由第 1 位说了算。取示例文章里那条 0100 授权的开头:位图,加上紧随其后的 16 个字符的数据:

723C448028C08000 1640000012345678

第一个字符是 7 = 0111——第 1 位是 0,位图到第 16 个字符就结束了。后面那段(164000001234…)是 DE2:LLVAR 长度 16,接着是卡号的开头。要是硬把这 16 个字符按位图的算法过一遍,会「解出」域 68、70、71、74、100、103、107、108、110、114、116、118、119、122、123、124、125——凭空多出 17 个根本没发过的域,而 DE2 之后每一个真实的域都会落到错的位置上。

识别信号恰恰就是这个模式:一条平平无奇的报文里突然散落一堆编号很高、很少用到的域。把这 32 个字符整段粘进位图计算器,它会指出来:第 1 位是 0,后 16 个字符不是位图,已忽略。

错误二:用了 65–128 的域,却忘了置第 1 位

组包方向的镜像错误。假设报文在域 2、3、4、11、41 之外还要带 DE90(原始数据元素,冲正用)。只在后面追加一张位置 26 置位的二级位图是不够的——第 1 位必须同时置上,而这会改掉整条位图的第一个字节:

位图接收方会怎么读
正确F020000000800000 0000004000000000首字符 F = 1111:第 1 位为 1 → 读 16 字节,解出 2、3、4、11、41、90
忘了第 1 位7020000000800000 0000004000000000首字符 7:第 1 位为 0 → 只读 8 字节,然后把 0000004000… 当成 DE2 的开头去解——从这里起全部错位

注意第一个字节:70 变成了 F0,因为加上了第 1 位的权重(80)。接收方不会以「位图非法」拒掉错的那条——它会在数据深处才失败,抛出一个让人摸不着头脑的长度或格式错误。计算器两个方向都设了防:域号框里只要出现大于 64 的域,第 1 位自动置上;粘一条首字符 ≥ 8 却只有 16 个字符的位图进去,它会提示二级位图缺失、这个值不完整。

拿到位图,先扫一眼这几条

为什么要有位图

ISO 8583 最多定义 128 个数据域,但一条典型报文只带其中 10–20 个。要是用定长布局,每条报文都得给全部 128 个域留位置——每笔交易浪费几百个字节,再乘以几十亿笔。位图花 8 个字节(用到 64 以上的域时 16 个)说清「后面只有这些域」,让每条报文只携带自己需要的东西;接收方解析任何数据之前,查一个位就知道「DE55 在不在」。位图在 MTI 和数据域之间处于什么位置,见怎么读一条 ISO 8583 报文


👉 不想自己画位,想让工具把 64 位画给你看?位图计算器两个方向都能算——十六进制出域号、域号出十六进制;想看位图在完整报文里怎么干活,把真实示例里的报文粘进解析器

延伸阅读