最近在做POS接入涉及到如何正确解析ISO8583协议的问题,遇到了一些很讨厌的问题今天将他们总结一

下写在博客中,供大家参考。

1.  对于小白首先要了解什么是ISO8583协议,请参考该文章http://www.itpub.net/thread-419521-1-1.html  讲解的非常详细。

2 .了解完ISO853协议以后,考虑用JAVA怎么解析8583协议报文。网上百度了下说到可以使用J8583CN来解析,下载地址http://sourceforge.net/projects/j8583cn/ 下载完后里        面有个example的目录运行Example.java就可以运行起来了。但是这里的J8583CN完全不能正常解析真实场合中的报文数据,

需要手工修改里面的解析方法。在这里我只说需要修改的几个重要点,其它要注意的地方大家参考部分资料就能解决了。

(a)根据《第七卷-中国银联POS前置系统指南》中讲到的ISO8583协议报文格式如下 TPDU+报文头+应用数据(ISO8583MSG)
         TPDU 说明:长度为10 个字节, 压缩时用BCD 码表示为5 个字节长度的数值。 报文头说明:总长度为12 字节,压缩时用BCD 码表示为6 个字节长度的数值。

如整消费交易消息:6132003215010200302004c020c09811000000000000000001000133021000123762258857

41255749d0000101296490017105603532303739303030303031333332303630313230303033313536e6b

52efda2c3f13726000000000000000014220006060006013242414635334638

这里TPDU省略了,
消息头:613200321501(这个是自定义没有明确固定的数据,每家公司可能都不一样)
I SO8583数据:(
消息类型-0200
位图描述-302004c020c09811
位图数据-00000000000000000100013302100012376225885741255749d0000101296490017
105603532303739303030303031333332303630313230303033313536e6b52efda2c3f13726000000000000000014220006060006013242414635334638 )   
(b)仔细阅读《第七卷-中国银联POS前置系统指南》中位图的详细描述
         域22,3个字节的定长数字字符域,压缩时用右靠BCD码表示的2个字节的定长域。说明该位图数据在传输时使用BCD编码的
         域63, ANS...163(LLLVAR),3个字节的长度值+最大163个字节的数据。压缩时用右靠BCD码表示的2个字节的长度值+用ASCII码表示的最大163个字节的数据。

仔细看位图描述就会发现有的域使用BCD编码,有的不是。问题就出在了那种变长的数据处理如LLVR和LLLVR的处理。

比如变长位域长度是经过BCD编码的,而对应的数据却不是BCD编码的或者数据是用ASCII码表示的(刚接触时不仔细看《第七卷-中国银联POS前置系统指南》会误认为都是BCD编码)。比如

44域 AN..25,2个字节长度+ 最大25个字节的数据。压缩时用右靠BCD码表示的1个字节的长度值+用ASCII码表示的最大25个字节的数据。
 60域 N...17(LLLVAR),3个字节的长度值+最大17个字节的数字字符域。压缩时用右靠BCD码表示的2个字节的长度值+用左靠BCD码表示的最大9个字节的数据。
 这时候需要先读取BCD编码的数据长度,然后将BCD码转换为十进制数据,十进制数就是对应的数据长度。这时候根据长度取后面的数据需要区位图是BCD编码和ASCII码

1.如果变长是ASCII码:如果是ASCII码的方式直接根据分析的十进制整数乘以2就是对应待取数据的长度,

为什么要乘以2因为数据包通过POS机发出来的包都是经过BCD编码的,2位BCD码表示一字节,所以在

数据报文byte[]中需要乘以2.

2.如果是BCD编码的:算出来的长度不需要乘以2,但是如果长度是奇数需要加一变成偶数,因为经过BCD

编码位数不足会补0,所以需要判断奇数还是偶数长度。

这里已经描述完了解析时要注意的特别点。J8583CN中修改的文件是cnFieldParseInfo.java,修改的方法
 "public cnValue<?> parse(byte[] buf, int pos, int bitSetIndex) throws ParseException " 修改方法中内容如下  
  if (type == cnType.LLVAR) {

//原始写法
//length = ((buf[pos] - 48) * 10) + (buf[pos + 1] - 48);
//return new cnValue<String>(type, new String(buf, pos + 2, length));//修改后的写法
if (bitSetIndex == 44) {
length = ((buf[pos] - 48) * 10) + (buf[pos + 1] - 48);
length=length*2;
return new cnValue<String>(type, new String(buf, pos + 2, length));
} else {
length = ((buf[pos] - 48) * 10) + (buf[pos + 1] - 48);
// 修改caiqiang-2015-08-25 判断取数据如果是奇数加一个补成偶数
if (length % 2 == 1) {
length = length + 1;
}
return new cnValue<String>(type, new String(buf, pos + 2, length));
}} else if (type == cnType.LLLVAR) {
//原始写法
//length = ((buf[pos] - 48) * 100) + ((buf[pos + 1] - 48) * 10) + (buf[pos + 2] - 48);
//return new cnValue<String>(type, new String(buf, pos + 3, length));//修改后的写法
if (bitSetIndex == 63 || bitSetIndex == 62) {
String lengthBcd = new String(buf, pos, 4);// 取得BCD码数据
length = Hex.BCDtoInt(lengthBcd);// BCD码转换为十进制数据
length=length*2;
return new cnValue<String>(type, new String(buf, pos + 4, length));} else {
String lengthBcd = new String(buf, pos, 4);// 取得BCD码数据
length = Hex.BCDtoInt(lengthBcd);// BCD码转换为十进制数据
// 判断奇数还是偶数 压缩BCD码后是偶数长度
if (length % 2 == 1) {
length = length + 1;
}
return new cnValue<String>(type, new String(buf, pos + 4, length));}}

原始报文如:6132003215010200302004c020c0981100000000000000000100013302100012376225

885741255749d000010129649001710560353230373930303030303133333230363031323030303331

3536e6b52efda2c3f13726000000000000000014220006060006013242414635334638

10:07:32,599 DEBUG: parsing config from xml file: [config.xml]
  typeid: [0200]
  hearder: [613200321501]
  位图数据: [302004c020c09811]
  bitmap data(binary format): [0011000000100000000001001100000000100000110000001001100000010001]
  bitmap(1-128): [{3, 4, 11, 22, 25, 26, 35, 41, 42, 49, 52, 53, 60, 64}]
  fieldid=[3] <NUMERIC> [000000] ---> [000000]
  fieldid=[4] <AMOUNT> [000000000001] ---> [0.01]
  fieldid=[11] <ALPHA> [000133] ---> [000133]
  fieldid=[22] <NUMERIC> [0210] ---> [0210]
  fieldid=[25] <NUMERIC> [00] ---> [00]
  fieldid=[26] <NUMERIC> [12] ---> [12]
  fieldid=[35] <LLVAR> [6225885741255749d000010129649001710560] ---> [6225885741255749d000010129649001710560]
  fieldid=[41] <ALPHA> [3532303739303030] ---> [3532303739303030]
  fieldid=[42] <ALPHA> [303031333332303630313230303033] ---> [303031333332303630313230303033]
  fieldid=[49] <ALPHA> [313536] ---> [313536]
  fieldid=[52] <ALPHA> [e6b52efda2c3f137] ---> [e6b52efda2c3f137]
  fieldid=[53] <ALPHA> [2600000000000000] ---> [2600000000000000]
  fieldid=[60] <LLLVAR> [22000606000601] ---> [22000606000601]
  fieldid=[64] <ALPHA> [3242414635334638] ---> [3242414635334638]

J8583CN解析ISO8583协议报文注意点相关推荐

  1. rtsp协议报文解析-首部字段解析

    前言 网上关于rtsp的文章很多,但大多是抽象的理论介绍,从理论学习到实际上手开发往往还有一段距离.然而,没有实际开发经验的支撑,理论又很难理解到位. 本系列文章将从流媒体协议的基础原理开始,通过抓包 ...

  2. springboot接收HL7协议报文 HAPI(SpringBoot版本)

    1.maven依赖 <dependency><groupId>ca.uhn.hapi</groupId><artifactId>hapi-base< ...

  3. 金融交易报文ISO8583协议

    前言 最初,金融系统只有IBM这些大公司来提供设备,象各种主机与终端等,后来有很多大大小小的公司进入,怎样设计一个报文协议,解决各公司金融系统之间的报文交换,暂且称该协议叫做ISO8583协议.例如& ...

  4. 深入理解金融交易报文Iso8583协议

    前言 思考 字段域定义 字段域解释 举个栗子 前言 最初,金融系统只有IBM这些大公司来提供设备,象各种主机与终端等,后来有很多大大小小的公司进入,怎样设计一个报文协议,解决各公司金融系统之间的报文交 ...

  5. DNS传输协议解析!pcap报文中的域名获取

    回想一下,当我们想访问谷歌的时候,通常输入域名(网址):https://www.google.com,其实这就是一个域名. DNS 解析过程涉及将主机名(例如 https://www.google.c ...

  6. 西门子PLC的S7协议报文解析说明

    我们以S7的1500系列来查看握手和读取.写入[字Word或者位Bit]命令报文 以下报文不做说明时都是十六进制字节. 西门子PLC需要连接成功后发送两次握手命令方可进行读写通信. 西门子PLC的S7 ...

  7. ModbusTCP协议报文解析

    ModbusTCP协议报文解析 报文格式 交互(通信)标识:2个字节 为此次通信事务处理标识符,一般每次通信之后将被要求加1以区别不同的通信数据报文. 协议标识:2个字节 表示该条指令遵循Modbus ...

  8. JAVA实现报文解析:协议的数据类型和完整的报文结构解析

    **JAVA实现GBT32960报文解析系列文章链接:** JAVA实现GBT32960报文解析(一):协议的数据类型和完整的报文结构解析 JAVA实现GBT32960报文解析(二):数据包结构解析源 ...

  9. LWM2M协议报文怎么解析

    LWM2M (Lightweight M2M) 协议是一种用于 M2M (Machine to Machine) 通信的协议,常用于 IoT (Internet of Things) 设备之间的通信. ...

最新文章

  1. android xml文件格式,android xml 资源文件中几个格式(@ ? @* @+)的含义
  2. Spark NaiveBayes Demo 朴素贝叶斯分类算法
  3. 英语阅读理解关于计算机,一篇摘选的关于计算机的英语阅读材料,对大家的英语也许会有提高!...
  4. git解决 remote: Permission to wuheng1991/site-manager.git denied to XXX
  5. 创建数据库以及该数据库下的表单
  6. python去年软件排行_2016 年有哪些好的 Python 机器学习开源项目?
  7. matlab二重定积分_matlab求二重积分
  8. 药品信息管理系统php,医药行业信息化管理系统
  9. unity打开android界面报错,Unity3D与Android交互介绍.docx
  10. 问答网站Stack Overflow的成功之道
  11. 墨言教育插画干货分享||日本插画为什么独树一帜,那么受欢迎
  12. Linux如何制作efi启动盘,教你制作macOS+Ubuntu+WindowsPE超级启动盘(仅支持UEFI)
  13. Molecular weight相对分子质量
  14. css 设置鼠标滑过变色效果
  15. NVIDIA支持CUDA的显卡选型简述
  16. 三坐标程序是C语言,三坐标程序编写系统及方法
  17. Nodejs+vue+elementui汽车销售网站管理系统
  18. ICASSP2020中语音合成部分论文阅读(未完待续)
  19. 低头敲代码,抬头看方向!| Java15新特性发布
  20. 深入浅出JS定时器:从setTimeout到setInterval

热门文章

  1. 求解线性同余方程--扩展欧几里得
  2. iOS8 定位新增功能
  3. 银河麒麟V10服务器系统安装教程及注意事项
  4. mail163企业邮箱从哪申请,tom企业邮箱怎么样?
  5. 咱就是说,方言配音的软件能有多少
  6. 170929 逆向-Reversing.kr(Ransomware)
  7. Python自学指南-你好啊!Python
  8. 201.微信公众号开发【文本消息】
  9. VI 之快速查找定位
  10. 2000-2020年上市公司制造业数据/制造业上市公司数据