waysun一路陽(yáng)光

          不輕易服輸,不輕言放棄.--心是夢(mèng)的舞臺(tái),心有多大,舞臺(tái)有多大。踏踏實(shí)實(shí)做事,認(rèn)認(rèn)真真做人。

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            167 隨筆 :: 1 文章 :: 64 評(píng)論 :: 0 Trackbacks

          前段時(shí)間做了一個(gè)涉及到IS08583報(bào)文協(xié)議的項(xiàng)目,自己總結(jié)寫(xiě)了這篇附有java源代碼的文章,希望能給大家提供一些幫助,本文分四個(gè)部分介紹IS08583報(bào)文協(xié)議包的處理及如何解析請(qǐng)求包及怎樣封裝返回包,

          一:IS08583包介紹:

               ISO8583包(簡(jiǎn)稱(chēng)8583包)是一個(gè)國(guó)際標(biāo)準(zhǔn)的包格式,最多由128個(gè)字段域組成,每個(gè)域都有統(tǒng)一的規(guī)定,并有定長(zhǎng)與變長(zhǎng)之分。
               8583包前面一段為位圖,用來(lái)確定包的字段域組成情況。其中位圖是8583包的靈魂,它是打包解包確定字段域的關(guān)鍵, 而了解每個(gè)字段域的屬性則是填寫(xiě)數(shù)據(jù)的基礎(chǔ)。   

           1:位圖說(shuō)明:

               位置:在8583包的第1 位
               格式:定長(zhǎng)  
               類(lèi)型:B16(二進(jìn)制16位,16*8=128bit)  
               描述:  
               如將位圖的第一位設(shè)為'1',表示使用擴(kuò)展位圖(128個(gè)域),否則表示只使用基本位圖(64個(gè)域)。  
               如使用某數(shù)據(jù)域,應(yīng)在位圖中將相應(yīng)的位設(shè)位'1',如使用41域,需將位圖的41位設(shè)為'1'。  
               選用條件:如使用65到128域,需設(shè)位圖域第一位為'1'  
          2:域的定義:  
          typedef struct ISO8583  
          {  
              int bit_flag;            /*域數(shù)據(jù)類(lèi)型0 -- string, 1 -- int, 2 -- binary*/  
              char *data_name;  /*域名*/  
              int length;             /*數(shù)據(jù)域長(zhǎng)度*/  
              int length_in_byte;/*實(shí)際長(zhǎng)度(如果是變長(zhǎng))*/  
              int variable_flag;   /*是否變長(zhǎng)標(biāo)志0:否 2:2位變長(zhǎng), 3:3位變長(zhǎng)*/  
              int datatyp;         /*0 -- string, 1 -- int, 2 -- binary*/  
              char *data;         /*存放具體值*/  
              int attribute;      /*保留*/  
          } ISO8583;

          二:定義BitMap類(lèi)

          類(lèi)說(shuō)明:根據(jù)ISO8583 包的域定義,定義BitMap類(lèi)存儲(chǔ)每個(gè)域的信息。例如:

          package com.lottery.pos.model;

          public  class BitMap {
           private int bit; //位
           private int bittype; //數(shù)據(jù)類(lèi)型 1 ascii 2 binary
           private int variable;  //是否變長(zhǎng)0 不是 2 兩位變長(zhǎng) 3 三位變長(zhǎng)
           private int len; //數(shù)據(jù)長(zhǎng)度
           private byte[] dat; //數(shù)據(jù)
           
           public int getBit() {
            return bit;
           }
           public void setBit(int bit) {
            this.bit = bit;
           }
           public int getBittype() {
            return bittype;
           }
           public void setBittype(int bittype) {
            this.bittype = bittype;
           }
           public int getVariable() {
            return variable;
           }
           public void setVariable(int variable) {
            this.variable = variable;
           }
           public byte[] getDat() {
            return dat;
           }
           public void setDat(byte[] dat) {
            this.dat = dat;
           }
           public int getLen() {
            return len;
           }
           public void setLen(int len) {
            this.len = len;
           }


          }

           

          三:定義PortConfig類(lèi)

          類(lèi)說(shuō)明:定義配置信息類(lèi)。根據(jù)此類(lèi)解析和封裝數(shù)據(jù)。例如:

          package com.lottery.pos.model;

          public class PortConfig {
           /**
            * 存放所有接口的配置信息
            * [][0] bit     位:在Map中的位
            * [][1] type   類(lèi)型:1 ascii 2 binary
            * [][2] len    長(zhǎng)度:(對(duì)定長(zhǎng)有效)
            * [][3] varLen 變長(zhǎng):0非變長(zhǎng) 2位變長(zhǎng) 3位變長(zhǎng)
            */
           // 定義一個(gè)二位數(shù)組存放配置信息。
           public static final  int[][] config= {
             {11,1,6,0},
             {12,1,6,0},
             {13,1,4,0},
             {32,1,11,0},
             {37,1,12,0},
             {39,1,2,0},
             {40,2,50,2},
             {41,1,8,0},
             {48,1,52,3},
             {120,2,128,3},
             };

          四:定義BitMapiso類(lèi)

          類(lèi)說(shuō)明:此類(lèi)提供解析請(qǐng)求包和封裝信息包兩個(gè)方法,例如:

          package com.lottery.pos.utils;

          import java.util.ArrayList;
          import java.util.List;

          import com.lottery.pos.model.BitMap;

          public class BitMapiso {

           /**
            * 解析請(qǐng)求包
            * @param body
            * @param config
            * @return List
            */
           @SuppressWarnings("unchecked")
           public static List unpackRequest(byte[] body, int[][] config) {
            List outList = new ArrayList();
            // 取得除信息類(lèi)型以外的包信息。也就是取得位圖的初始位置。
            byte[] realbody = new byte[body.length - 4];
            System.arraycopy(body, 4, realbody, 0, realbody.length);
            // 取得位圖
            byte[] map = null;
            byte[] map8 = new byte[8];
            System.arraycopy(realbody, 0, map8, 0, 8);
            boolean[] bmap8 = LoUtils.getBinaryFromByte(map8);
            if (bmap8[1]) {
            // 如果第一位為1,則是可擴(kuò)展位圖,設(shè)為16字節(jié)長(zhǎng)度。
             map = new byte[16];
             System.arraycopy(realbody, 0, map, 0, 16);
            } else {
             map = map8;
            }
            boolean[] bmap = LoUtils.getBinaryFromByte(map);

            int tmplen = map.length;
            for (int i = 2; i < bmap.length; i++) {
             if (bmap[i]) {
              //BitMap bitMap = null;
              // 尋找位圖中的1對(duì)應(yīng)的數(shù)據(jù)
              int bit=-1;
              for (int j = 0; j < config.length; j++) {
               if (config[j][0] == i) {
                bit=j;
                break;
               }
              }
              BitMap outBitMap = new BitMap();
              outBitMap.setBit(i);
              outBitMap.setBittype(config[bit][1]);
              //len對(duì)變長(zhǎng)是無(wú)用的。
              outBitMap.setLen(config[bit][2]);
              outBitMap.setVariable(config[bit][3]);
              byte[] nextData = null;
              if (config[bit][3] > 0) {
               //取出變長(zhǎng)部分的值。
               int varLen = config[bit][3];
               if (config[bit][1] == 2) {
                varLen = varLen - 1;
               }
               byte[] varValue = new byte[varLen];
               System.arraycopy(realbody, tmplen, varValue, 0, varValue.length);
               int datLen = 0;
               if (config[bit][1] == 2) {
                datLen = LoUtils.bcdToint(varValue);
               } else {
                datLen = byteToInt(varValue);
               }

               tmplen += varLen;
               // 取出變長(zhǎng)部分后帶的值。
               nextData = new byte[datLen];

               System.arraycopy(realbody, tmplen, nextData, 0,nextData.length);
               tmplen += nextData.length;
              } else {
               nextData = new byte[config[bit][2]];
               System.arraycopy(realbody, tmplen, nextData, 0,nextData.length);
               tmplen += config[bit][2];
              }
              outBitMap.setDat(nextData);
              outList.add(outBitMap);
             }
            }

            return outList;
           }

           

           /**
            * 打包響應(yīng)包,不包括消息類(lèi)型
            * @param list
            * @return byte[]
            */
           @SuppressWarnings("unchecked")
           public static byte[] PackResponse(List list) {
            int len = 16;
            for (int i = 0; i < list.size(); i++) {
             BitMap bitMap = (BitMap) list.get(i);
             // 計(jì)算請(qǐng)求包總長(zhǎng)度
             if (bitMap.getBittype() == 2) {
              if (bitMap.getVariable() > 0) {
               len += bitMap.getVariable() - 1 + bitMap.getDat().length;
              } else {
               len += bitMap.getVariable() + bitMap.getDat().length;
              }
             } else {
              len += bitMap.getVariable() + bitMap.getDat().length;
             }
            }
            byte[] body = new byte[len];
            // 位圖
            boolean[] bbitMap = new boolean[129];
            bbitMap[1] = true;
            int temp = (bbitMap.length - 1) / 8;
            for (int j = 0; j < list.size(); j++) {
             BitMap bitMap = (BitMap) list.get(j);
             bbitMap[bitMap.getBit()] = true;
             byte[] bitmap = LoUtils.getByteFromBinary(bbitMap);
             System.arraycopy(bitmap, 0, body, 0, bitmap.length);
             // 數(shù)據(jù)
             if (bitMap.getVariable() > 0) {
              // 數(shù)據(jù)是可變長(zhǎng)的:拼變長(zhǎng)的值
              byte[] varValue = null;
              if (bitMap.getBittype() == 2) {
               varValue = LoUtils.StrToBCDBytes(String.format("%0"+ bitMap.getVariable() + "d",bitMap.getDat().length));
              } else {
               varValue = String.format("%0" + bitMap.getVariable() + "d",bitMap.getDat().length).getBytes();
              }
              System.arraycopy(varValue, 0, body, temp, varValue.length);
              temp += varValue.length;
              // 拼變長(zhǎng)部分后所帶的數(shù)的值。
              System.arraycopy(bitMap.getDat(), 0, body, temp, bitMap.getDat().length);
              temp += bitMap.getDat().length;
             } else {
              // 數(shù)據(jù)是固定長(zhǎng)度的。
              byte dat[] =new byte[bitMap.getLen()];
              if (bitMap.getDat().length!=bitMap.getLen()){     
               System.arraycopy(bitMap.getDat(), 0, dat, 0, bitMap.getLen());
              }else{
               dat=bitMap.getDat();
              } 
              System.arraycopy(dat, 0, body, temp, dat.length);
              temp += bitMap.getDat().length;
             }
            }
            return body;
           }

           

           

           

          package com.lottery.utils;

          import java.io.BufferedInputStream;
          import java.io.ByteArrayOutputStream;
          import java.io.IOException;

          import javax.servlet.http.HttpServletRequest;

          import sun.misc.BASE64Decoder;
          import sun.misc.BASE64Encoder;

          /**
           * 編碼與數(shù)據(jù)類(lèi)型類(lèi)
           *
           * @author LLH
           */
          public class LoUtils
          {
           private static BASE64Encoder encoder = new BASE64Encoder ();
           private static BASE64Decoder decoder = new BASE64Decoder ();
           
           /**
            * BASE64 編碼
            *
            * @param s
            * @return
            */
           public static String encodeBufferBase64(byte [] buff)
           {
            return buff == null ? null : encoder.encode (buff);
           }
           
           /**
            * BASE64解碼
            *
            * @param s
            * @return
            */
           public static byte [] decodeBufferBase64(String s)
           {
            try
            {
             return s == null ? null : decoder.decodeBuffer (s);
            }catch (IOException e)
            {
             e.printStackTrace ();
            }
            return null;
           }
           
           /**
            * BASE64 字節(jié)數(shù)組編碼
            *
            * @param s
            * @return String
            */
           public static String encodeBase64(byte [] s)
           {
            if(s == null)
             return null;
            String res = new BASE64Encoder ().encode (s);
            res = res.replace ("\n","");
            res = res.replace ("\r","");
            return res;
           }
           
           /**
            * BASE64解碼
            *
            * @param s
            * @return
            */
           public static byte [] decodeBase64(byte [] buff)
           {
            if(buff == null)
             return null;
            BASE64Decoder decoder = new BASE64Decoder ();
            try
            {
             byte [] b = decoder.decodeBuffer (new String (buff));
             
             return b;
            }catch (Exception e)
            {
             return null;
            }
           }
           
           /**
            * 將reauest里的數(shù)據(jù)包轉(zhuǎn)成字符串
            *
            * @param request
            * @return String
            */
           public static String getRequestBodyTxt(HttpServletRequest request)
           {
            // 接收手機(jī)傳過(guò)來(lái)的參數(shù)
            BufferedInputStream bufferedInputStream = null;
            // 此類(lèi)實(shí)現(xiàn)了一個(gè)輸出流,其中的數(shù)據(jù)被寫(xiě)入一個(gè)字節(jié)數(shù)組
            ByteArrayOutputStream bytesOutputStream = null;
            String body = null;
            try
            {
             
             // BufferedInputStream 輸入流
             bufferedInputStream = new BufferedInputStream (
              request.getInputStream ());
             bytesOutputStream = new ByteArrayOutputStream ();
             // 寫(xiě)入數(shù)據(jù)
             int ch;
             while ((ch = bufferedInputStream.read ()) != -1)
             {
              bytesOutputStream.write (ch);
             }
             // 轉(zhuǎn)換為String類(lèi)型
             body = new String (bytesOutputStream.toByteArray (),"UTF-8");
            }catch (Exception ex)
            {
             ex.printStackTrace ();
            }
            finally
            {
             // 關(guān)閉此輸入流并釋放與該流關(guān)聯(lián)的所有系統(tǒng)資源。
             try
             {
              bytesOutputStream.flush ();
              bytesOutputStream.close ();
              bufferedInputStream.close ();
             }catch (IOException e)
             {
              e.printStackTrace ();
             }
            }
            return body;
           }
           
           /**
            * 將reauest里的數(shù)據(jù)包轉(zhuǎn)成字節(jié)數(shù)組
            *
            * @param request
            * @return
            */
           public static byte [] getRequestBodyByte(HttpServletRequest request)
           {
            // 接收手機(jī)傳過(guò)來(lái)的參數(shù)
            BufferedInputStream bufferedInputStream = null;
            // 此類(lèi)實(shí)現(xiàn)了一個(gè)輸出流,其中的數(shù)據(jù)被寫(xiě)入一個(gè)字節(jié)數(shù)組
            ByteArrayOutputStream bytesOutputStream = null;
            byte [] body = null;
            try
            {
             // BufferedInputStream 輸入流
             bufferedInputStream = new BufferedInputStream (
              request.getInputStream ());
             bytesOutputStream = new ByteArrayOutputStream ();
             // 寫(xiě)入數(shù)據(jù)
             int ch;
             while ((ch = bufferedInputStream.read ()) != -1)
             {
              bytesOutputStream.write (ch);
             }
             // 轉(zhuǎn)換為String類(lèi)型
             body = bytesOutputStream.toByteArray ();
            }catch (Exception ex)
            {
             ex.printStackTrace ();
            }
            finally
            {
             // 關(guān)閉此輸入流并釋放與該流關(guān)聯(lián)的所有系統(tǒng)資源。
             try
             {
              bytesOutputStream.flush ();
              bytesOutputStream.close ();
              bufferedInputStream.close ();
             }catch (IOException e)
             {
              e.printStackTrace ();
             }
            }
            return body;
           }
           
           public static String getEigthBitsStringFromByte(int b)
           {
            // if this is a positive number its bits number will be less
            // than 8
            // so we have to fill it to be a 8 digit binary string
            // b=b+100000000(2^8=256) then only get the lower 8 digit
            b |= 256; // mark the 9th digit as 1 to make sure the string
            // has at
            // least 8 digits
            String str = Integer.toBinaryString (b);
            int len = str.length ();
            return str.substring (len - 8,len);
           }
           
           public static byte getByteFromEigthBitsString(String str)
           {
            // if(str.length()!=8)
            // throw new Exception("It's not a 8 length string");
            byte b;
            // check if it's a minus number
            if(str.substring (0,1).equals ("1"))
            {
             // get lower 7 digits original code
             str = "0" + str.substring (1);
             b = Byte.valueOf (str,2);
             // then recover the 8th digit as 1 equal to plus
             // 1000000
             b |= 128;
            }
            else
            {
             b = Byte.valueOf (str,2);
            }
            return b;
           }
           
           /**
            * 將一個(gè)16字節(jié)數(shù)組轉(zhuǎn)成128二進(jìn)制數(shù)組
            *
            * @param b
            * @return
            */
           public static boolean [] getBinaryFromByte(byte [] b)
           {
            boolean [] binary = new boolean [b.length * 8 + 1];
            String strsum = "";
            for (int i = 0;i < b.length;i++ )
            {
             strsum += getEigthBitsStringFromByte (b [i]);
            }
            for (int i = 0;i < strsum.length ();i++ )
            {
             if(strsum.substring (i,i + 1).equalsIgnoreCase ("1"))
             {
              binary [i + 1] = true;
             }
             else
             {
              binary [i + 1] = false;
             }
            }
            return binary;
           }
           
           /**
            * 將一個(gè)128二進(jìn)制數(shù)組轉(zhuǎn)成16字節(jié)數(shù)組
            *
            * @param binary
            * @return
            */
           public static byte [] getByteFromBinary(boolean [] binary)
           {
            
            int num = (binary.length - 1) / 8;
            if((binary.length - 1) % 8 != 0)
            {
             num = num + 1;
            }
            byte [] b = new byte [num];
            String s = "";
            for (int i = 1;i < binary.length;i++ )
            {
             if(binary [i])
             {
              s += "1";
             }
             else
             {
              s += "0";
             }
            }
            String tmpstr;
            int j = 0;
            for (int i = 0;i < s.length ();i = i + 8)
            {
             tmpstr = s.substring (i,i + 8);
             b [j] = getByteFromEigthBitsString (tmpstr);
             j = j + 1;
            }
            return b;
           }
           
           /**
            * 將一個(gè)byte位圖轉(zhuǎn)成字符串
            *
            * @param b
            * @return
            */
           public static String getStrFromBitMap(byte [] b)
           {
            String strsum = "";
            for (int i = 0;i < b.length;i++ )
            {
             strsum += getEigthBitsStringFromByte (b [i]);
            }
            return strsum;
           }
           
           /**
            * bytes轉(zhuǎn)換成十六進(jìn)制字符串
            *
            * @param b
            * @return
            */
           public static String byte2HexStr(byte [] b)
           {
            String hs = "";
            String stmp = "";
            for (int n = 0;n < b.length;n++ )
            {
             stmp = (Integer.toHexString (b [n] & 0XFF));
             if(stmp.length () == 1)
              hs = hs + "0" + stmp;
             else
              hs = hs + stmp;
            }
            return hs.toUpperCase ();
           }
           
           private static byte uniteBytes(String src0, String src1)
           {
            byte b0 = Byte.decode ("0x" + src0).byteValue ();
            b0 = (byte) (b0 << 4);
            byte b1 = Byte.decode ("0x" + src1).byteValue ();
            byte ret = (byte) (b0 | b1);
            return ret;
           }
           
           /**
            * 十六進(jìn)制字符串轉(zhuǎn)換成bytes
            *
            * @param src
            * @return
            */
           public static byte [] hexStr2Bytes(String src)
           {
            int m = 0, n = 0;
            int l = src.length () / 2;
            byte [] ret = new byte [l];
            for (int i = 0;i < l;i++ )
            {
             m = i * 2 + 1;
             n = m + 1;
             ret [i] = uniteBytes (src.substring (i * 2,m),
              src.substring (m,n));
            }
            return ret;
           }
           
           /**
            * 將String轉(zhuǎn)成BCD碼
            *
            * @param s
            * @return
            */
           public static byte [] StrToBCDBytes(String s)
           {
            
            if(s.length () % 2 != 0)
            {
             s = "0" + s;
            }
            ByteArrayOutputStream baos = new ByteArrayOutputStream ();
            char [] cs = s.toCharArray ();
            for (int i = 0;i < cs.length;i += 2)
            {
             int high = cs [i] - 48;
             int low = cs [i + 1] - 48;
             baos.write (high << 4 | low);
            }
            return baos.toByteArray ();
           }
           
           /**
            * 將BCD碼轉(zhuǎn)成int
            *
            * @param b
            * @return
            */
           public static int bcdToint(byte [] b)
           {
            StringBuffer sb = new StringBuffer ();
            for (int i = 0;i < b.length;i++ )
            {
             int h = ((b [i] & 0xff) >> 4) + 48;
             sb.append ((char) h);
             int l = (b [i] & 0x0f) + 48;
             sb.append ((char) l);
            }
            return Integer.parseInt (sb.toString ());
           }
           
           /**
            * 輸出調(diào)試信息
            *
            * @param str
            */
           public static void trace(String str)
           {
          //  System.out.println ("["
          //   + (new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss.S")).format (new Date ())
          //   + "]>" + str);
           }
          }

           

           

          源代碼測(cè)試沒(méi)有問(wèn)題。

          posted on 2011-06-20 14:58 weesun一米陽(yáng)光 閱讀(3703) 評(píng)論(1)  編輯  收藏

          評(píng)論

          # re: IS08583報(bào)文協(xié)議包的解析和封裝java源代碼 【轉(zhuǎn)】 2013-08-08 10:32 九十度
          你好,可以把源代碼發(fā)一份給我嗎,172581565@qq.com  回復(fù)  更多評(píng)論
            


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 土默特左旗| 浪卡子县| 孟村| 华蓥市| 黔江区| 林州市| 临颍县| 台州市| 灵川县| 齐齐哈尔市| 五莲县| 尚志市| 张家港市| 乌拉特中旗| 清涧县| 建始县| 绥芬河市| 大化| 博罗县| 奇台县| 南陵县| 莱芜市| 奎屯市| 巴林左旗| 普宁市| 曲靖市| 崇义县| 芦山县| 图木舒克市| 新郑市| 隆安县| 上高县| 曲阜市| 阳谷县| 滨海县| 伊金霍洛旗| 朔州市| 库车县| 田阳县| 杨浦区| 临城县|