开源J8583与J8583CN简略介绍

2024-03-19 21:58

本文主要是介绍开源J8583与J8583CN简略介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

因工作需要,近期研究了ISO8583协议。

1、站在巨人的肩膀上,初学者想了解什么是ISO8583协议,请参考该文章http://www.itpub.net/thread-419521-1-1.html 讲解的非常详细。

2、考虑用JAVA解析8583协议报文的时候,一开始根据协议规则写了一套处理程序。后来同事提点网上有开源的jar包。于是一番折腾从网上找到一堆材料,整理分析下,以便来日方长。

开源jar包有两个:

J8583:国外大佬开源的,面向全球化的一套jar。

下载路径:https://sourceforge.net/projects/j8583/files/

J8583CN:国内大佬在J8583基础上做的中国化jar。

此版本我现在用的比较流畅的版本来源:

https://git.oschina.net/ipan/public/tree/master/J8583CN

(参考:http://blog.sina.com.cn/s/blog_667ac0360102vonm.html)

两个jar包的解析信息都配置在j8583.xml下,存在一定差异。

J8583:

引入J8583的jar包(IDEA:File->Project Structure ->Modules 最右竖列的“+” -> JARs or directories)

在这里插入图片描述
j8583.xml的配置:

<?xml version="1.0" encoding="UTF-8"?>
<j8583-config><encode>gbk</encode><!-- J8583 --><!-- 报文类型 --><header type="0200">0200</header><!-- 创建模板 --><!-- 解析模板 --><parse type="0200"><field num="2" type="LLVAR" /><field num="3" type="LLVAR" /><field num="4" type="NUMERIC" length="4" /><field num="5" type="NUMERIC" length="4" /><field num="6" type="NUMERIC" length="4" /><field num="7" type="NUMERIC" length="1" /><field num="8" type="NUMERIC" length="1" /><field num="43" type="LLVAR" /><field num="44" type="LLVAR" /><field num="45" type="LLVAR" /></parse>
</j8583-config>

组包和解析测试代码(输入输出流可以相应修改,例子为了方便对文件操作):

package com.swiftplus.posservice.core.service.impl;import com.solab.iso8583.IsoMessage;
import com.solab.iso8583.IsoType;
import com.solab.iso8583.MessageFactory;
import com.solab.iso8583.parse.ConfigParser;import java.io.FileInputStream;
import java.io.FileOutputStream;public class TestJ8583 {public static void main(String[] args) throws Exception {write();
//		read();}//组装ISO8583报文private static void write() throws Exception{MessageFactory messageFactory = new MessageFactory();//这里的参数关系到最终生成的报文格式messageFactory.setBinaryHeader(false);messageFactory.setBinaryFields(false);messageFactory.setUseBinaryBitmap(true);messageFactory.setForceStringEncoding(true);messageFactory.setUseBinaryMessages(false);//hexToInt(200)这玩意应该是国外的报文类型IsoMessage isoMessage = messageFactory.newMessage(hexToInt(200));
//        isoMessage.setValue(2,"222",IsoType.NUMERIC,5);//8583域值设置isoMessage.setValue(2,"222",IsoType.ALPHA,5);//报文头设置isoMessage.setIsoHeader("pos header");String basepath = TestJ8583.class.getClassLoader().getResource("").getPath();String path2 =  basepath+ "/messagedata.out";FileOutputStream fout = new FileOutputStream(path2);//		isoMessage.writeData();isoMessage.write(fout,  0);fout.close();}//解析ISO8583报文private static void read() throws Exception{//读文件String basepath = TestJ8583.class.getClassLoader().getResource("").getPath();String path2 =  basepath+ "/messagedata.out";FileInputStream fin = new FileInputStream(path2);//四位报文全部长度
//		byte[] buf = new byte[4];
//		fin.read(buf);
//		int len = byteArrayToInt(buf);
//		System.out.println(len);
//		buf = new byte[len];byte[] buf = new byte[1024];fin.read(buf);fin.close();//初始化获取解析配置文件j8583.xmlMessageFactory messageFactory = ConfigParser.createDefault();//与组包一致messageFactory.setBinaryHeader(false);messageFactory.setBinaryFields(false);messageFactory.setUseBinaryBitmap(true);messageFactory.setForceStringEncoding(true);messageFactory.setUseBinaryMessages(false);//解析报文IsoMessage isoMessage = messageFactory.parseMessage(buf,10);print(isoMessage);}private static int intToHex(int n) {StringBuffer s = new StringBuffer();String a;char []b = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};while(n != 0){s = s.append(b[n%16]);n = n/16;}a = s.reverse().toString();return Integer.valueOf(a);}private static int hexToInt(int n) {return Integer.parseInt(String.valueOf(n), 16);}// 输出一个报文内容private static void print(IsoMessage m) {System.out.println("----------------------------------------------------- ");System.out.println("Message Header = [" + m.getIsoHeader() + "]");System.out.println("Message TypeID = [" +  m.getType() + "]");for (int i = 2; i < 128; i++) {if (m.hasField(i)) {System.out.println("FieldID: " + i+ " <" + m.getField(i).getType()+ ">\t[" + m.getObjectValue(i)+ "]\t[" + m.getField(i).toString() + "]");}}}}

--------------------------------快乐的分割线----------------------------------------------

J8583CN:

在这里插入图片描述
j8583.xml的配置:

<?xml version="1.0" encoding="UTF-8"?>
<j8583cn-config><encode>gbk</encode><!-- J8583CN --><!-- 报文类型 --><header length="19">0200</header><!-- 解析模板 --><parseinfo msgtypeid="0200"><field id="3" datatype="NUMERIC" length="6"></field><field id="4" datatype="ALPHA" length="4"></field><field id="5" datatype="NUMERIC" length="5"></field><field id="6" datatype="LLVAR"></field><field id="7" datatype="BINARY" length="3"></field><field id="11" datatype="NUMERIC" length="8"></field><field id="50" datatype="NUMERIC" length="8"></field></parseinfo>
</j8583cn-config>

组包和解析测试代码:

package com.swiftplus.posservice.core.service.impl;import java.io.FileInputStream;
import java.io.FileOutputStream;import org.apache.commons.lang3.StringUtils;
import org.zyp.cn8583.cnMessage;
import org.zyp.cn8583.cnMessageFactory;
import org.zyp.cn8583.cnSystemTraceNumGenerator;
import org.zyp.cn8583.cnType;
import org.zyp.cn8583.impl.cnSimpleSystemTraceNumGen;
import org.zyp.cn8583.parse.cnConfigParser;public class TestJ8583CN {private static cnSystemTraceNumGenerator TRACENUM_GEN = new cnSimpleSystemTraceNumGen((int) (System.currentTimeMillis() % 1000));public static void main(String[] args) throws Exception {
//		write();read();}private static String createIsoHeader(NetIdType type, String seqNo) {String tpdu = "00000";return tpdu + type.getCode() + seqNo + "0000";  // TPDU+网络标识+交易流水号}protected static cnMessage createIsoMessage(String msgType, String trscode) {// 创建报文cnMessage message = new cnMessageFactory().newMessage(msgType,19);message.setBinary(false); // 对于域不使用二进制int trsSeqNo = TRACENUM_GEN.nextTrace();String trsSeqNoStr = StringUtils.leftPad(trsSeqNo + "", 8, '0');// 设置头部String headMsg = createIsoHeader(NetIdType.ATM, trsSeqNoStr);message.setMessageHeaderData(0, headMsg.getBytes());// TODO: 设置公共报文体...message.setValue(3, trscode, cnType.NUMERIC, 6); // 3	交易处理码	N6	M	Rmessage.setValue(11, trsSeqNoStr, cnType.NUMERIC, 8); // 11	流水号	N8	M	Rreturn message;}public static void write() throws Exception {cnMessage message = createIsoMessage("0200", "160300");message.setValue(4, "abc", cnType.ALPHA, 4); // 右侧填空格message.setValue(5, 123, cnType.NUMERIC, 5); // 左侧填0
//        message.setValue(6, "abcdefghijklmn", cnType.LLVAR, 0); // 变长字符byte[] buf = new byte[3];buf[0] = 49; // 1buf[1] = 50; // 2buf[2] = 51; // 3
//		String encStr = HexCodec.encPack(buf); // 特殊二进制手动编码message.setValue(7, buf, cnType.BINARY, 3);String basepath = TestJ8583.class.getClassLoader().getResource("").getPath();String path2 =  basepath+ "/messagedata.out";FileOutputStream fout = new FileOutputStream(path2);
//        Socket socket = new Socket("127.0.0.1", 60000);
//        OutputStream outputStream = socket.getOutputStream();
//        message.write(outputStream, 2, 16);
//        outputStream.flush();message.write(fout, 2, 16);fout.close();}public static void read() throws Exception {byte[] buf = new byte[2];String basepath = TestJ8583.class.getClassLoader().getResource("").getPath();String path2 =  basepath+ "/messagedata.out";
//        FileInputStream fin = new FileInputStream(path2"messagedata.out");FileInputStream fin = new FileInputStream(path2);fin.read(buf);	// 读二个字节的数据(将报文长度信息读出)int len = byteArrayToInt(buf);System.out.println(len);buf = new byte[len];fin.read(buf);	// 从第五个字节读取len个自己的数据到buf中fin.close();cnMessageFactory mfact = cnConfigParser.createDefault();mfact.setUseBinary(false);cnMessage m = mfact.parseMessage(buf, mfact.getHeaderLengthAttr("0200"));	// 解析print(m);System.out.println("--- field7 value ---");
//		String v7 = (String) m.getObjectValue(7);
//		byte[] v7by = HexCodec.encUnpack(v7); // 对特殊二进制手动解码byte[] v7by = (byte[]) m.getObjectValue(7);for (byte b : v7by) {System.out.println(Integer.toHexString(b));}}public static int byteArrayToInt(byte[] bytes) {int len = bytes.length;int value = 0;// 由高位到低位for (int i = 0; i < len; i++) {int shift = (len - 1 - i) * 8;value += (bytes[i] & 0x000000FF) << shift;// 往高位游}return value;}// 输出一个报文内容private static void print(cnMessage m) {System.out.println("----------------------------------------------------- ");System.out.println("Message Header = [" + new String(m.getmsgHeader()) + "]");System.out.println("Message TypeID = [" +  m.getMsgTypeID() + "]");for (int i = 2; i < 128; i++) {if (m.hasField(i)) {System.out.println("FieldID: " + i+ " <" + m.getField(i).getType()+ ">\t[" + m.getObjectValue(i)+ "]\t[" + m.getField(i).toString() + "]");}}}
}

国产版:

1、将j8583的type(用来获取解析格式的key),改成了适用于国产的报文类型。

2、将jar组出来的报文总长度多样化,可以分别使用十进制或十六进制。而J8583只支持十六进制。

3、更多细节等着小伙伴们补充。

这篇关于开源J8583与J8583CN简略介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/827350

相关文章

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

阿里开源语音识别SenseVoiceWindows环境部署

SenseVoice介绍 SenseVoice 专注于高精度多语言语音识别、情感辨识和音频事件检测多语言识别: 采用超过 40 万小时数据训练,支持超过 50 种语言,识别效果上优于 Whisper 模型。富文本识别:具备优秀的情感识别,能够在测试数据上达到和超过目前最佳情感识别模型的效果。支持声音事件检测能力,支持音乐、掌声、笑声、哭声、咳嗽、喷嚏等多种常见人机交互事件进行检测。高效推

图神经网络模型介绍(1)

我们将图神经网络分为基于谱域的模型和基于空域的模型,并按照发展顺序详解每个类别中的重要模型。 1.1基于谱域的图神经网络         谱域上的图卷积在图学习迈向深度学习的发展历程中起到了关键的作用。本节主要介绍三个具有代表性的谱域图神经网络:谱图卷积网络、切比雪夫网络和图卷积网络。 (1)谱图卷积网络 卷积定理:函数卷积的傅里叶变换是函数傅里叶变换的乘积,即F{f*g}

金融业开源技术 术语

金融业开源技术  术语 1  范围 本文件界定了金融业开源技术的常用术语。 本文件适用于金融业中涉及开源技术的相关标准及规范性文件制定和信息沟通等活动。

安全管理体系化的智慧油站开源了。

AI视频监控平台简介 AI视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。用户只需在界面上进行简单的操作,就可以实现全视频的接入及布控。摄像头管理模块用于多种终端设备、智能设备的接入及管理。平台支持包括摄像头等终端感知设备接入,为整个平台提

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

C++——stack、queue的实现及deque的介绍

目录 1.stack与queue的实现 1.1stack的实现  1.2 queue的实现 2.重温vector、list、stack、queue的介绍 2.1 STL标准库中stack和queue的底层结构  3.deque的简单介绍 3.1为什么选择deque作为stack和queue的底层默认容器  3.2 STL中对stack与queue的模拟实现 ①stack模拟实现

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页:https://tangyuan96.github.io/minigpt_3d_project_page/ 代码:https://github.com/TangYuan96/MiniGPT-3D 论文:https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA,被ACM MM2024接收,只拥有47.8M的可训练参数,在一张RTX