首先 抽象一个类 表示每个域的数据
public class Area {
private int areaNo;//域序号
private String areaName;//域名称
private int leng;//域长度(定长)
private AreaDataType dataType;//域数据类型
private AreaLenType lenType;//域长度类型
private boolean isDynamicLen;//是否是变长
private String data;//数据
private int dynamicLen;//变长长度
private int dynamicLen_2_3;//(变长长度是2/3字节)
public Area() {
super();
// TODO Auto-generated constructor stub
}
public Area(int areaNo, String areaName, int leng, AreaDataType dataType, AreaLenType lenType,
boolean isDynamicLen,int dynamicLen_2_3) {
super();
this.areaNo = areaNo;
this.areaName = areaName;
this.leng = leng;
this.dataType = dataType;
this.lenType = lenType;
this.isDynamicLen = isDynamicLen;
this.dynamicLen_2_3 = dynamicLen_2_3;
}
public int getDynamicLen_2_3() {
return dynamicLen_2_3;
}
public void setDynamicLen_2_3(int dynamicLen_2_3) {
this.dynamicLen_2_3 = dynamicLen_2_3;
}
public int getDynamicLen() {
return dynamicLen;
}
public void setDynamicLen(int dynamicLen) {
this.dynamicLen = dynamicLen;
}
public boolean isDynamicLen() {
return isDynamicLen;
}
public void setDynamicLen(boolean isDynamicLen) {
this.isDynamicLen = isDynamicLen;
}
public int getAreaNo() {
return areaNo;
}
public void setAreaNo(int areaNo) {
this.areaNo = areaNo;
}
public String getAreaName() {
return areaName;
}
public void setAreaName(String areaName) {
this.areaName = areaName;
}
public int getLeng() {
return leng;
}
public void setLeng(int leng) {
this.leng = leng;
}
public AreaDataType getDataType() {
return dataType;
}
public void setDataType(AreaDataType dataType) {
this.dataType = dataType;
}
public AreaLenType getLenType() {
return lenType;
}
public void setLenType(AreaLenType lenType) {
this.lenType = lenType;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
@Override
public String toString() {
return "Area [areaNo=" + areaNo + ", areaName=" + areaName + ", leng=" + leng + ", dataType=" + dataType
+ ", lenType=" + lenType + ", data=" + data + "]";
}
}
写两个枚举 一个表示该域的数据类型 一个表示数据长度类型
public enum AreaDataType {
ASCII,
BCD,
BINARY
}
public enum AreaLenType {
ASCII,
BCD,
BINARY
}
配置8583域的属性
public class BaoWenConfig {
public Area area0 = new Area(0, "msgtype", 4, AreaDataType.BCD, AreaLenType.BCD, false,0);
public Area area1 = new Area(1, "拓展位图", 8, AreaDataType.BINARY, AreaLenType.BCD, false,0);
public Area area2 = new Area(2, "主账号", 19, AreaDataType.BCD, AreaLenType.BCD, true,2);
public Area area3 = new Area(3, "交易处理码", 6, AreaDataType.BCD, AreaLenType.BCD, false,0);
public Area area4 = new Area(4, "交易金额", 12, AreaDataType.BCD, AreaLenType.BCD, false,0);
public Area area11 = new Area(11, "系统跟踪号", 6, AreaDataType.BCD, AreaLenType.BCD, false,0);
public Area area12 = new Area(12, "受卡发方所在地时间", 6, AreaDataType.BCD, AreaLenType.BCD, false,0);
public Area area13 = new Area(13, "受卡发方所在地日期", 4, AreaDataType.BCD, AreaLenType.BCD, false,0);
public Area area14 = new Area(14, "卡有效期", 4, AreaDataType.BCD, AreaLenType.BCD, false,0);
public Area area15 = new Area(15, "清算日期", 4, AreaDataType.BCD, AreaLenType.BCD, false,0);
public Area area22 = new Area(22, "服务点输入方式码", 3, AreaDataType.BCD, AreaLenType.BCD, false,0);
public Area area23 = new Area(23, "卡序列号", 3, AreaDataType.BCD, AreaLenType.BCD, false,0);
public Area area25 = new Area(25, "服务点条件码", 2, AreaDataType.BCD, AreaLenType.BCD, false,0);
public Area area26 = new Area(26, "服务点PIN获取码", 2, AreaDataType.BCD, AreaLenType.BCD, false,0);
public Area area32 = new Area(32, "受理机构标识码", 11, AreaDataType.BCD, AreaLenType.BCD, true,2);
public Area area35 = new Area(35, "第二磁道数据", 37, AreaDataType.BCD, AreaLenType.BCD, true,2);
public Area area36 = new Area(36, "第三磁道数据", 104, AreaDataType.BCD, AreaLenType.BCD, true,3);
public Area area37 = new Area(37, "检索参考号", 12, AreaDataType.ASCII, AreaLenType.BCD, false,0);
public Area area38 = new Area(38, "授权标识应答码", 6, AreaDataType.ASCII, AreaLenType.BCD, false,0);
public Area area39 = new Area(39, "应答码", 2, AreaDataType.ASCII, AreaLenType.BCD, false,0);
public Area area41 = new Area(41, "受卡机终端标识码", 8, AreaDataType.ASCII, AreaLenType.BCD, false,0);
public Area area42 = new Area(42, "受卡方标识码", 15, AreaDataType.ASCII, AreaLenType.BCD, false,0);
public Area area43 = new Area(43, "商户名称", 40, AreaDataType.ASCII, AreaLenType.ASCII, false,0);
public Area area44 = new Area(44, "附加响应数据", 25, AreaDataType.ASCII, AreaLenType.BCD, true,2);
public Area area48 = new Area(48, "附加数据-私有", 512, AreaDataType.BCD, AreaLenType.BCD, true,3);
public Area area49 = new Area(49, "交易货币代码", 3, AreaDataType.ASCII, AreaLenType.BCD, false,0);
public Area area52 = new Area(52, "个人标识码数据", 16, AreaDataType.BCD, AreaLenType.BCD, false,0);
public Area area53 = new Area(53, "安全控制信息", 16, AreaDataType.BCD, AreaLenType.BCD, false,0);
public Area area54 = new Area(54, "实际金额", 32, AreaDataType.ASCII, AreaLenType.BCD, true,3);
public Area area55 = new Area(55, "基于PBOC借贷记标准的IC卡数据", 255, AreaDataType.BINARY, AreaLenType.BCD, true,3);
public Area area57 = new Area(57, "pos版本", 42, AreaDataType.ASCII, AreaLenType.BCD, true,3);
public Area area58 = new Area(58, "基于PBOC电子钱包/存折IC卡标准的交易数据", 100, AreaDataType.BINARY, AreaLenType.BCD, true,3);
public Area area60 = new Area(60, "自定义域", 100, AreaDataType.BCD, AreaLenType.BCD, true,3);
public Area area61 = new Area(61, "原始信息域", 200, AreaDataType.BCD, AreaLenType.BCD, true,3);
public Area area62 = new Area(62, "原始信息域", 200, AreaDataType.BINARY, AreaLenType.BCD, true,3);
public Area area63 = new Area(63, "金融网络数据", 200, AreaDataType.ASCII, AreaLenType.BCD, true,3);
public Area area64 = new Area(64, "MAC", 8, AreaDataType.ASCII, AreaLenType.BCD, false,0);
public ArrayList areas = new ArrayList(){/**
*
*/
private static final long serialVersionUID = 4868905912449475521L;
{
add(area0);
add(area1);
add(area2);
add(area3);
add(area4);
add(area11);
add(area12);
add(area13);
add(area14);
add(area15);
add(area22);
add(area23);
add(area25);
add(area26);
add(area32);
add(area35);
add(area36);
add(area37);
add(area38);
add(area39);
add(area41);
add(area42);
add(area43);
add(area44);
add(area48);
add(area49);
add(area52);
add(area53);
add(area54);
add(area55);
add(area57);
add(area58);
add(area60);
add(area61);
add(area62);
add(area63);
add(area64);
}};
public Area getAreaWithAreaNo(int no){
Area result = null;
for (Area area : areas) {
if(area.getAreaNo() == no){
result = area;
break;
}
}
return result;
}
}
处理8583报文的主要类
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class Deal8583 {
private static BASE64Encoder encoder = new BASE64Encoder();
private static BASE64Decoder decoder = new BASE64Decoder();
public static String byte2hex(byte[] b) // 二进制转字符串
{
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1){
hs = hs + "0" + stmp;
}
else{
hs = hs + stmp;
}
}
return hs;
}
public static byte[] hex2byte(String str) { // 字符串转二进制
if (str == null){
return null;
}
str = str.trim();
int len = str.length();
if (len == 0 || len % 2 == 1){
return null;
}
byte[] b = new byte[len / 2];
try {for (int i = 0; i < str.length(); i += 2) {
b[i / 2] = (byte) Integer.decode("0x" + str.substring(i, i + 2)).intValue();
}
return b;
} catch (Exception e) {
return null;
}
}
public static String asciiToString(String value)
{
StringBuffer sbu = new StringBuffer();
String[] chars = value.split(",");
for (int i = 0; i < chars.length; i++) {
sbu.append((char) Integer.parseInt(chars[i]));
}
return sbu.toString();
}
public static String stringToAscii(String value)
{
StringBuffer sbu = new StringBuffer();
char[] chars = value.toCharArray();
for (int i = 0; i < chars.length; i++) {
if(i != chars.length - 1)
{
sbu.append((int)chars[i]).append(",");
}
else {
sbu.append((int)chars[i]);
}
}
return sbu.toString();
}
public static String byteToASCString(byte[] bArray){
String strASC="";
String strTemp="";
for(int i=0;i> 4) + 48;
sb.append((char) h);
int l = (b[i] & 0x0f) + 48;
sb.append((char) l);
}
return Integer.parseInt(sb.toString());
}
// 将byte数组bRefArr转为一个整数,字节数组的低位是整型的低字节位
public static int byteToInt(byte[] bRefArr) {
int iOutcome = 0;
byte bLoop;
for (int i = 0; i < bRefArr.length; i++) {
bLoop = bRefArr[i];
iOutcome += (bLoop & 0xFF) << (8 * i);
}
return iOutcome;
}
/**
* 向服务器 发送8583报文
*
* @param send8583Str 发送给服务器的报文
*
* @param host 主机地址IP
*
* @param port 端口号
*
* @return 返回的数据
* */
public static String send8583(String send8583Str,String host,int port) throws Exception{
//客户端请求与本机在20011端口建立TCP连接
Socket client = new Socket(host, port);
client.setSoTimeout(70000);
//获取Socket的输出流,用来发送数据到服务端
PrintStream out = new PrintStream(client.getOutputStream());
//获取Socket的输入流,用来接收从服务端发送过来的数据
InputStream buf = client.getInputStream();
String str = "mpos-"+send8583Str;
//发送数据到服务端
out.println(str);
try{
byte[] b = new byte[1024];
int rc=0;
int c = 0;
while( (rc = buf.read(b, c, 1024) )>=0){
c = buf.read(b, 0, rc);
}
String returnStr = byte2hex(b);
String string = returnStr;
String str16 = string.substring(0, 4);
int leng = Integer.parseInt(str16,16);
String result = string.substring(0, leng*2 + 4);
if (client!=null) {
client.close();
}
return result;
}catch(Exception e){
e.printStackTrace();
System.out.println("Time out, No response");
}
if (client!=null) {
client.close();
}
return null;
}
public static String bitmapHex2Binary(String bitmap){
String bitMapStr = bitmap;
if (bitMapStr == null || bitMapStr.length() % 2 != 0)
return null;
String bString = "", tmp;
for (int i = 0; i < bitMapStr.length(); i++)
{
tmp = "0000"
+ Integer.toBinaryString(Integer.parseInt(bitMapStr
.substring(i, i + 1), 16));
bString += tmp.substring(tmp.length() - 4);
}
return bString;
}
public static String getBitMapStr(String str8583){
return str8583.substring(30, 46);
}
/**
* 获得报文的位图数组
*
* */
public static ArrayList getBitMap(String bitMapStr){
ArrayList bitMaps = new ArrayList();
if (bitMapStr == null || bitMapStr.length() % 2 != 0)
return null;
String bString = "", tmp;
for (int i = 0; i < bitMapStr.length(); i++)
{
tmp = "0000"
+ Integer.toBinaryString(Integer.parseInt(bitMapStr
.substring(i, i + 1), 16));
bString += tmp.substring(tmp.length() - 4);
}
for(int i = 0 ; i < bString.length() ; i ++){
char c = bString.charAt(i);
int flag = Integer.parseInt(String.format("%c", c));
if (flag==1) {
bitMaps.add(i+1);
}
}
return bitMaps;
}
/**
* 解析8583报文
* @param str8583 8583报文
* @param resultMap 存放8583全部解析后的Map
* @return 填充完成的域数组集合
*
* */
public static ArrayList jiexi8583(String str8583,HashMap resultMap){
//报文总长
int currentIndex = 0;
String lenStr = str8583.substring(currentIndex, 4);
resultMap.put("LEN", lenStr);
currentIndex += lenStr.length();
//tpdu
String TPDUStr = str8583.substring(currentIndex, currentIndex+10);
resultMap.put("TPDU", TPDUStr);
currentIndex += TPDUStr.length();
//msghead
String MSGHEADStr = str8583.substring(currentIndex,currentIndex+12);
resultMap.put("MSGHEAD", MSGHEADStr);
currentIndex += MSGHEADStr.length();
//报文type
String TYPEStr = str8583.substring(currentIndex, currentIndex+4);
resultMap.put("TYPE", TYPEStr);
currentIndex += TYPEStr.length();
//位图
String BITMAPStr = str8583.substring(currentIndex,currentIndex+16);
resultMap.put("BITMAP", BITMAPStr);
currentIndex += BITMAPStr.length();
//位图数组
ArrayList bitmaps = getBitMap(BITMAPStr);
//报文配置
BaoWenConfig config = new BaoWenConfig();
//根据位图找到报文对应的域
ArrayList areas = new ArrayList();
for (Integer areaNo : bitmaps) {
areas.add(config.getAreaWithAreaNo(areaNo));
}
//为每个域填充信息
for (Area area : areas) {
String areaDataStr = null;//用来存放该域的数据
if( area.isDynamicLen()){//如果是变长的话
if(area.getDataType()==AreaDataType.BCD && area.getLenType() == AreaLenType.BCD){
String dylenStr = null;
int useLen = 0;
if (area.getDynamicLen_2_3() == 2) {
dylenStr = str8583.substring(currentIndex,currentIndex+2);
currentIndex += 2;
int dataLen = Integer.parseInt(dylenStr);
if (dataLen %2 ==0) {
useLen = dataLen;
}else{
useLen = dataLen + 1;
}
}else if(area.getDynamicLen_2_3() == 3){
dylenStr = str8583.substring(currentIndex,currentIndex+4);
currentIndex += 4;
int dataLen = Integer.parseInt(dylenStr);
if (dataLen %2 ==0) {
useLen = dataLen;
}else{
useLen = dataLen + 1;
}
}
areaDataStr = str8583.substring(currentIndex, currentIndex+useLen);
currentIndex += areaDataStr.length();
resultMap.put(String.format("%d", area.getAreaNo()), areaDataStr);
area.setLeng(Integer.parseInt(dylenStr));
}else if(area.getDataType()==AreaDataType.ASCII && area.getLenType() == AreaLenType.BCD){
String dylenStr = str8583.substring(currentIndex,currentIndex+4);
currentIndex += 4;
areaDataStr = str8583.substring(currentIndex, currentIndex+Integer.parseInt(dylenStr)*2);
currentIndex +=areaDataStr.length();
resultMap.put(String.format("%d", area.getAreaNo()), areaDataStr);
area.setLeng(Integer.parseInt(dylenStr));
}else if(area.getDataType()==AreaDataType.BINARY && area.getLenType() == AreaLenType.BCD){
String dylenStr = str8583.substring(currentIndex,currentIndex+4);
currentIndex += 4;
areaDataStr = str8583.substring(currentIndex, currentIndex+Integer.parseInt(dylenStr)*2);
currentIndex +=areaDataStr.length();
resultMap.put(String.format("%d", area.getAreaNo()), areaDataStr);
area.setLeng(Integer.parseInt(dylenStr));
}
}else{//如果是固定长度
if(area.getDataType()==AreaDataType.BCD && area.getLenType() == AreaLenType.BCD){
areaDataStr = str8583.substring(currentIndex,currentIndex+area.getLeng());
resultMap.put(String.format("%d", area.getAreaNo()) , areaDataStr);
currentIndex += areaDataStr.length() %2 ==0 ?areaDataStr.length():areaDataStr.length()+1 ;
}else if(area.getDataType()==AreaDataType.ASCII && area.getLenType() == AreaLenType.BCD){
areaDataStr = str8583.substring(currentIndex,currentIndex+area.getLeng() * 2);
resultMap.put(String.format("%d", area.getAreaNo()) , areaDataStr);
currentIndex += areaDataStr.length();
}
}
//存放到该域
area.setData(areaDataStr);
}
return areas;
}
public static void main(String[] args) throws Exception {
String baowen = "012760000300006022000000000200702406C020C09A111662596543203269930000000000008890000006972212071000010012376259654320326993D2212201000007820000003130303030303132333034343532303438313230303031313536EF7F40420E3741FE260000000000000001649F26083AE8A83B8A54F8739F2701809F101307020103A00000010A0100000000008D9318249F3704E97798B59F3602017D950500000000009A031702219C01009F02060000008890005F2A02015682027C009F1A0201569F03060000000000009F3303E0E1C89F34030200009F3501229F1E0838373937303835378408A0000003330101029F090200309F4104000006979F6310303130353030303000000000000000000014220000020006013246373437303042";
HashMap resultMap = new HashMap();
ArrayList areas = jiexi8583(baowen,resultMap);
System.out.println(resultMap);
for (Area area : areas) {
System.out.println(area);
}
}
}