Java版ISO8583包解析工具
阿新 • • 發佈:2019-02-01
1、解析類
/** * ISO8583資料解析器<br> * ISO8583資料結構:2位元組訊息型別(BCD碼) + 域1至域64/128<br> * @author yanhang0610 */ public class Iso8583Package { // 報文結構 private byte[] messageTypeBytes = new byte[2]; // BCD編碼的訊息型別 // 位元圖,如"01001000...",位於第1域 private byte[] bitMapBytes = new byte[8]; // 預設變長欄位長度儲存格式為壓縮的BCD碼 private Iso8583Package.VarLengthFormat varLengthFormat = Iso8583Package.VarLengthFormat.BCD; // 存放各個域的配置資訊(<0, Iso8583Field>。。。) private Map<Integer, Iso8583Package.Iso8583Field> iso8583FieldConfigs = new HashMap<Integer, Iso8583Package.Iso8583Field>(); // 存放各個域的值(<0, byte[]>、<1, byte[]>。。。) private Map<Integer, byte[]> fieldsData = new HashMap<Integer, byte[]>(); /** * 建構函式,預設無擴充套件點陣圖,變長欄位長度儲存格式為壓縮的BCD碼 * @param iso8583configFilePathName */ public Iso8583Package(String iso8583configFilePathName) { this(iso8583configFilePathName, false, Iso8583Package.VarLengthFormat.BCD); } /** * 建構函式,預設無擴充套件點陣圖,自定義變長欄位長度儲存格式 * @param iso8583configFilePathName * @param varLengthFormat 變長欄位長度儲存格式 */ public Iso8583Package(String iso8583configFilePathName, Iso8583Package.VarLengthFormat varLengthFormat) { this(iso8583configFilePathName, false, varLengthFormat); } /** * 建構函式 * @param iso8583configFilePathName * @param isExtendBitMap 是否擴充套件點陣圖 * @param varLengthFormat 變長欄位長度儲存格式 */ public Iso8583Package(String iso8583configFilePathName, boolean isExtendBitMap, Iso8583Package.VarLengthFormat varLengthFormat) { // 設定擴充套件位元圖 if (isExtendBitMap) { String bitMapStr = "1" + ByteUtils.getBinaryString(new byte[16]).substring(1); this.bitMapBytes = ByteUtils.binaryStringToBytes(bitMapStr); } // 載入配置檔案 this.iso8583FieldConfigs = this.loadConfigFile(iso8583configFilePathName); if (varLengthFormat != null) { this.varLengthFormat = varLengthFormat; } } /** * 載入iso8583配置檔案 */ private Map<Integer, Iso8583Package.Iso8583Field> loadConfigFile(String iso8583configFilePathName) { Map<Integer, Iso8583Package.Iso8583Field> map = new HashMap<Integer, Iso8583Package.Iso8583Field>(); XmlBean xml = new XmlBean(iso8583configFilePathName); List<Element> configs = xml.getChildNodes("/iso8583Fields"); for (Element element : configs) { List<Element> subConfigs = element.elements(); String subTagName = ""; String subTagValue = ""; int fieldNum = 0; Iso8583Package.Iso8583Field iso8583Field = new Iso8583Package.Iso8583Field(); for (Element subElement : subConfigs) { subTagName = subElement.getName(); subTagValue = subElement.getTextTrim(); try { if ("fieldNum".equalsIgnoreCase(subTagName)) { fieldNum = Integer.parseInt(subTagValue); iso8583Field.setFieldNum(fieldNum); } else if ("fieldName".equalsIgnoreCase(subTagName)) { iso8583Field.setFieldName(subTagValue); } else if ("dataStorageFormat".equalsIgnoreCase(subTagName)) { if ("ASCII".equalsIgnoreCase(subTagValue)) { iso8583Field.setDataStorageFormat(Iso8583Package.DataStorageFormat.ASCII); } else if ("BINARY".equalsIgnoreCase(subTagValue)) { iso8583Field.setDataStorageFormat(Iso8583Package.DataStorageFormat.BINARY); } else if ("BCD".equalsIgnoreCase(subTagValue)) { iso8583Field.setDataStorageFormat(Iso8583Package.DataStorageFormat.BCD); } else { throw new RuntimeException("配置檔案出錯,第[" + fieldNum + "]域dataStorageFormat配置錯誤[\"" + subTagValue + "\"]!"); } } else if ("length".equalsIgnoreCase(subTagName)) { iso8583Field.setLength(Integer.parseInt(subTagValue)); } else if ("fieldFormat".equalsIgnoreCase(subTagName)) { if ("None".equalsIgnoreCase(subTagValue)) { iso8583Field.setFieldFormat(Iso8583Package.FieldFormat.NONE); } else if ("LVAR".equalsIgnoreCase(subTagValue)) { iso8583Field.setFieldFormat(Iso8583Package.FieldFormat.LVAR); } else if ("LLVAR".equalsIgnoreCase(subTagValue)) { iso8583Field.setFieldFormat(Iso8583Package.FieldFormat.LLVAR); } else if ("LLLVAR".equalsIgnoreCase(subTagValue)) { iso8583Field.setFieldFormat(Iso8583Package.FieldFormat.LLLVAR); } else if ("LLLLVAR".equalsIgnoreCase(subTagValue)) { iso8583Field.setFieldFormat(Iso8583Package.FieldFormat.LLLLVAR); } else { throw new RuntimeException("配置檔案出錯,第[" + fieldNum + "]域fieldFormat配置錯誤[\"" + subTagValue + "\"]!"); } } else if ("align".equalsIgnoreCase(subTagName)) { if ("Left".equalsIgnoreCase(subTagValue)) { iso8583Field.setAlign(Iso8583Package.Align.LEFT); } else if ("Right".equalsIgnoreCase(subTagValue)) { iso8583Field.setAlign(Iso8583Package.Align.RIGHT); } else { throw new RuntimeException("配置檔案出錯,第[" + fieldNum + "]域align配置錯誤[\"" + subTagValue + "\"]!"); } } else if ("padChar".equalsIgnoreCase(subTagName)) { if ("Null".equalsIgnoreCase(subTagValue)) { iso8583Field.setPadChar(Iso8583Package.PadChar.NULL); } else if ("Space".equalsIgnoreCase(subTagValue)) { iso8583Field.setPadChar(Iso8583Package.PadChar.SPACE); } else { throw new RuntimeException("配置檔案出錯,第[" + fieldNum + "]域padChar配置錯誤[\"" + subTagValue + "\"]!"); } } else { throw new RuntimeException("配置檔案出錯,找不到有效的配置項[FieldNum: " + fieldNum + "][TagName: \"" + subTagName + "\", TagValue: \"" + subTagValue + "\"]!"); } } catch (Exception e) { if (e instanceof NumberFormatException) { throw new RuntimeException("配置檔案出錯,數字值非法[FieldNum: " + fieldNum + "][TagName: \"" + subTagName + "\", TagValue: \"" + subTagValue + "\"]!"); } else { throw new RuntimeException(e.getMessage()); } } } if (fieldNum > 0) { map.put(fieldNum, iso8583Field); // System.out.println(iso8583Field.toString()); } } return map; } /** * 解析各個域的值 * @param iso8583FieldsBytes 域1~128的資料 * @return */ public Map<Integer, byte[]> parseFields(byte[] iso8583FieldsBytes) { Map<Integer, byte[]> fieldsData = new HashMap<Integer, byte[]>(); try { byte[] bitMapBytes = this.parseBitMap(iso8583FieldsBytes); fieldsData.put(new Integer(1), bitMapBytes); this.bitMapBytes = bitMapBytes; int idx = 0; // 指標 idx += bitMapBytes.length; String bitMapStr = ByteUtils.getBinaryString(bitMapBytes); int bitMapStrLength = bitMapStr.length(); Iso8583Package.FieldFormat fieldFormat = Iso8583Package.FieldFormat.NONE; for (int i = 1; i < bitMapStrLength; i++) { if (bitMapStr.charAt(i) == '1') { Integer fieldNum = i + 1; Iso8583Package.Iso8583Field fieldConfig = iso8583FieldConfigs.get(fieldNum); int fieldLength = 0; // 域佔用的位元組數(長度位元組和內容位元組總的位元組數) int length = fieldConfig.getLength(); // 域內容不同儲存格式下該格式對應的最大儲存個數 // 計算實際個數(比配LLLL表示的長度和配置檔案length值,LLLL長度不能大於length) fieldFormat = fieldConfig.getFieldFormat(); if (fieldFormat == Iso8583Package.FieldFormat.NONE) { // 無處理, length即為實際個數 } else { // 長度位元組數(LL..L 佔用的位元組數) int lengthBytesLength = this.getVarLengthBytesLength(fieldFormat); long varLength = 0; if (this.varLengthFormat == Iso8583Package.VarLengthFormat.BCD) { varLength = ByteUtils.readBCD(iso8583FieldsBytes, idx, lengthBytesLength); } else if (this.varLengthFormat == Iso8583Package.VarLengthFormat.ASCII) { varLength = ByteUtils.readLong(iso8583FieldsBytes, idx, lengthBytesLength); } else if (this.varLengthFormat == Iso8583Package.VarLengthFormat.NUMBER_STRING) { varLength = Long.parseLong(ByteUtils.readString(iso8583FieldsBytes, idx, lengthBytesLength)); } if (varLength <= length) { length = (int) varLength; // 變長長度不能大於length } else { throw new RuntimeException("[FieldNum: " + fieldNum + "]變長長度[" + varLength + "]不能大於配置檔案裡的length值[" + length + "]!"); } fieldLength += lengthBytesLength; } // 計算內容部分佔用的位元組數 int fieldContentLength = 0; // 域內容實際佔用的位元組數 Iso8583Package.DataStorageFormat dataStoreFormat = fieldConfig.getDataStorageFormat(); if (dataStoreFormat == Iso8583Package.DataStorageFormat.ASCII) { fieldContentLength = length; } else if (dataStoreFormat == Iso8583Package.DataStorageFormat.BCD) { fieldContentLength = length % 2 == 0 ? length / 2 : (length / 2 + 1); } else if (dataStoreFormat == Iso8583Package.DataStorageFormat.BINARY) { fieldContentLength = length; } else { return null; } fieldLength += fieldContentLength; byte[] fieldBytes = ByteUtils.getSubBytesByIndex(iso8583FieldsBytes, idx, idx + fieldLength - 1); fieldsData.put(new Integer(fieldNum), fieldBytes); idx += fieldLength; } } this.fieldsData = fieldsData; } catch (Exception e) { throw new RuntimeException("引數值[iso8583FieldsBytes]有誤!" + (e.getMessage() == null ? "" : e.getMessage())); } return fieldsData; } /******* 點陣圖 *************************************************************************/ /** * 從iso8583FieldsBytes解析點陣圖 */ private byte[] parseBitMap(byte[] iso8583FieldsBytes) { byte b0 = iso8583FieldsBytes[0]; String b0Str = ByteUtils.getBinaryString(new byte[] { b0 }); if (b0Str.startsWith("1")) { return ByteUtils.getSubBytesByIndex(iso8583FieldsBytes, 0, 15); } else { return ByteUtils.getSubBytesByIndex(iso8583FieldsBytes, 0, 7); } } /** * 點陣圖置位 * @param fieldNum 域,2-128,第1域為點陣圖,不做處理 * @param value 值,0或1 */ private void setBitMap(int fieldNum, int value) { if (fieldNum < 2 || fieldNum > bitMapBytes.length * 8 || (value != 0 && value != 1)) { return; } String bitMapStr = ByteUtils.getBinaryString(bitMapBytes); bitMapStr = bitMapStr.substring(0, fieldNum - 1) + value + (fieldNum == bitMapStr.length() ? "" : bitMapStr.substring(fieldNum)); this.bitMapBytes = ByteUtils.binaryStringToBytes(bitMapStr); this.fieldsData.put(new Integer(1), this.bitMapBytes); } /******* 賦值 *************************************************************************/ /** * 根據配置檔案裡的域配置進行設值(預設UTF-8編碼) * @param fieldNum * @param value 當域資料儲存格式為ASCII時,value可為任意字串;當儲存格式為BCD時,value應為整數形式的字串;當儲存格式為BINARY時,value應為由0-9A-F組成的十六進位制形式的字串。 * @return */ public boolean setField(int fieldNum, String value) { return setField(fieldNum, value, "UTF-8"); } /** * 根據配置檔案裡的域配置進行設值 * @param fieldNum * @param value 當域資料儲存格式為ASCII時,value可為任意字串;當儲存格式為BCD時,value應為整數形式的字串;當儲存格式為BINARY時,value應為由0-9A-F組成的十六進位制形式的字串。 * @param charsetName * @return */ public boolean setField(int fieldNum, String value, String charsetName) { try { Integer fieldNumInteger = new Integer(fieldNum); Iso8583Package.Iso8583Field fieldConfig = iso8583FieldConfigs.get(fieldNumInteger); // 域配置 Iso8583Package.DataStorageFormat dataStoreFormat = fieldConfig.getDataStorageFormat(); byte[] bytes = null; if (dataStoreFormat == Iso8583Package.DataStorageFormat.ASCII) { bytes = value.getBytes(charsetName); } else if (dataStoreFormat == Iso8583Package.DataStorageFormat.BCD) { boolean isFullBCD = true; if (value.length() % 2 != 0) { isFullBCD = false; if (fieldConfig.align == Iso8583Package.Align.LEFT) { value = value + "0"; } else { value = "0" + value; } } bytes = ByteUtils.hexStringToBytes(value); return setField(fieldNum, bytes, isFullBCD); } else if (dataStoreFormat == Iso8583Package.DataStorageFormat.BINARY) { bytes = ByteUtils.hexStringToBytes(value); } return setField(fieldNum, bytes); } catch (Exception e) { String msg = "域賦值出錯[FieldNum: " + fieldNum + ", Value(String): " + value + "]!"; throw new RuntimeException(e.getMessage() == null ? msg : (e.getMessage().startsWith("域賦值出錯") ? e.getMessage() : msg + e.getMessage())); } } /** * 根據配置檔案裡的域配置進行設值 * @param fieldNum * @param value * @return */ public boolean setField(int fieldNum, int value) { try { Integer fieldNumInteger = new Integer(fieldNum); Iso8583Package.Iso8583Field fieldConfig = iso8583FieldConfigs.get(fieldNumInteger); // 域配置 Iso8583Package.DataStorageFormat dataStoreFormat = fieldConfig.getDataStorageFormat(); byte[] bytes = null; if (dataStoreFormat == Iso8583Package.DataStorageFormat.ASCII) { bytes = ByteUtils.bytesTrimLeft(ByteUtils.intToBytes(value), (byte) 0x00); } else if (dataStoreFormat == Iso8583Package.DataStorageFormat.BCD) { boolean isFullBCD = true; String valueStr = value + ""; if (valueStr.length() % 2 != 0) { isFullBCD = false; if (fieldConfig.align == Iso8583Package.Align.LEFT) { valueStr = valueStr + "0"; } else { valueStr = "0" + valueStr; } } bytes = ByteUtils.hexStringToBytes(valueStr); return setField(fieldNum, bytes, isFullBCD); } else if (dataStoreFormat == Iso8583Package.DataStorageFormat.BINARY) { bytes = ByteUtils.bytesTrimLeft(ByteUtils.intToBytes(value), (byte) 0x00); } return setField(fieldNum, bytes); } catch (Exception e) { String msg = "域賦值出錯[FieldNum: " + fieldNum + ", Value(int): " + value + "]!"; throw new RuntimeException(e.getMessage() == null ? msg : (e.getMessage().startsWith("域賦值出錯") ? e.getMessage() : msg + e.getMessage())); } } /** * 根據配置檔案裡的域配置進行設值 * @param fieldNum * @param value 若欄位為BCD格式,則BCD個數為value.length * 2 * @return */ public boolean setField(int fieldNum, byte[] value) { return setField(fieldNum, value, true); } /** * 根據配置檔案裡的域配置進行設值 * @param fieldNum * @param value 若欄位為BCD格式,則BCD個數由isFullBCD決定 * @param isFullBCD 欄位為BCD格式時有效。當isFullBCD為true時,value裡儲存的都為BCD位數,此時傳入的BCD個數為value.length * 2;反之value裡有補位了一個BCD個數,傳入的BCD的個數應為value.length * 2 - 1。 * @return */ public boolean setField(int fieldNum, byte[] value, boolean isFullBCD) { try { Integer fieldNumInteger = new Integer(fieldNum); Iso8583Package.Iso8583Field fieldConfig = iso8583FieldConfigs.get(fieldNumInteger); // 域配置 Iso8583Package.DataStorageFormat dataStoreFormat = fieldConfig.getDataStorageFormat(); // 計算不同儲存型別實際佔用的儲存個數(非後續位元組數) int dataLength = 0; if (dataStoreFormat == Iso8583Package.DataStorageFormat.ASCII) { dataLength = value.length; } else if (dataStoreFormat == Iso8583Package.DataStorageFormat.BCD) { // 判斷value是否為有效的BCD值 if (!RegularUtils.doMatch("[0-9]*", ByteUtils.getHexString(value))) { throw new RuntimeException("域賦值出錯[FieldNum: " + fieldNum + ", Value(HEX): " + ByteUtils.getHexString(value) + "]!不是有效的BCD值"); } dataLength = value.length * 2; if (!isFullBCD) { dataLength = dataLength - 1; } } else if (dataStoreFormat == Iso8583Package.DataStorageFormat.BINARY) { dataLength = value.length; } else { return false; } // 判斷個數是否大於配置值 if (dataLength > fieldConfig.getLength()) { throw new RuntimeException("域賦值出錯[FieldNum: " + fieldNum + ", Value(HEX): " + ByteUtils.getHexString(value) + "]!長度大於配置值" + fieldConfig.getLength()); } // 封裝欄位值 Iso8583Package.FieldFormat fieldFormat = fieldConfig.getFieldFormat(); if (fieldFormat == Iso8583Package.FieldFormat.NONE) { // 定長 int fieldFixLength = fieldConfig.getLength(); // 配置項配置的定長長度,不同儲存型別佔用的儲存個數(非後續位元組數) // 計算定長佔用的位元組數 int fieldFixContentBytesLength = 0; // 域內容佔用的固定位元組數 if (dataStoreFormat == Iso8583Package.DataStorageFormat.ASCII) { fieldFixContentBytesLength = fieldFixLength; } else if (dataStoreFormat == Iso8583Package.DataStorageFormat.BCD) { fieldFixContentBytesLength = fieldFixLength % 2 == 0 ? fieldFixLength / 2 : (fieldFixLength / 2 + 1); } else if (dataStoreFormat == Iso8583Package.DataStorageFormat.BINARY) { fieldFixContentBytesLength = fieldFixLength; } if (value.length < fieldFixContentBytesLength) { byte padByte = (byte) (fieldConfig.getPadChar() == Iso8583Package.PadChar.NULL ? 0x00 : 0x20); if (fieldConfig.align == Iso8583Package.Align.LEFT) { value = ByteUtils.bytesPadRight(value, fieldFixContentBytesLength, padByte); } else if (fieldConfig.align == Iso8583Package.Align.RIGHT) { value = ByteUtils.bytesPadLeft(value, fieldFixContentBytesLength, padByte); } } } else { // 不定長 // 長度位元組數(LL..L 佔用的位元組數) int lengthBytesLength = this.getVarLengthBytesLength(fieldFormat); byte[] bytes = new byte[lengthBytesLength + value.length]; // 變長佔用lengthBytesLength位元組 if (this.varLengthFormat == Iso8583Package.VarLengthFormat.BCD) { ByteUtils.writeBCD(bytes, 0, dataLength, lengthBytesLength); // 用壓縮的BCD碼錶示 } else if (this.varLengthFormat == Iso8583Package.VarLengthFormat.ASCII) { ByteUtils.writeLong(bytes, 0, dataLength, lengthBytesLength); } else if (this.varLengthFormat == Iso8583Package.VarLengthFormat.NUMBER_STRING) { ByteUtils.writeString(bytes, 0, StringUtils.padLeft(dataLength + "", lengthBytesLength, '0'), lengthBytesLength); } else { return false; } System.arraycopy(value, 0, bytes, lengthBytesLength, value.length); value = bytes; } this.fieldsData.put(new Integer(fieldNum), value); setBitMap(fieldNum, 1); return true; } catch (Exception e) { String msg = "域賦值出錯[FieldNum: " + fieldNum + ", Value(byte[]): " + ByteUtils.getHexString(value) + "]!"; throw new RuntimeException(e.getMessage() == null ? msg : (e.getMessage().startsWith("域賦值出錯") ? e.getMessage() : msg + e.getMessage())); } } /******* 取值 *************************************************************************/ /** * 以16進位制字串格式讀取域的值,若讀取失敗則返回null * @param fieldNum * @return */ public String getFieldHexStringValue(int fieldNum) { try { byte[] bytes = this.getFieldBytesValue(fieldNum); return ByteUtils.getHexString(bytes); } catch (Exception e) { return null; } } /** * 以BCD格式讀取域的值,若讀取失敗則返回null * @param fieldNum * @param charsetName * @return */ public String getFieldBCDValue(int fieldNum) { try { String hex = getFieldHexStringValue(fieldNum); Iso8583Package.Iso8583Field fieldConfig = iso8583FieldConfigs.get(fieldNum); if (fieldConfig.getDataStorageFormat() == Iso8583Package.DataStorageFormat.BCD) { // BCD另行處理 int bcdCount = 0; // BCD個數 if (fieldConfig.fieldFormat == Iso8583Package.FieldFormat.NONE) { bcdCount = fieldConfig.getLength(); } else { bcdCount = this.getVarLength(fieldNum); } if (fieldConfig.getAlign() == Iso8583Package.Align.LEFT) { hex = hex.substring(0, bcdCount); } else { hex = hex.substring(hex.length() - bcdCount); } } return hex; } catch (Exception e) { return null; } } /** * 以String格式讀取域的值,編碼型別為charsetName,若讀取失敗則返回null * @param fieldNum * @param charsetName * @return */ public String getFieldStringValue(int fieldNum, String charsetName) { try { byte[] bytes = this.getFieldBytesValue(fieldNum); return new String(bytes, charsetName); } catch (Exception e) { return null; } } /** * 以String格式讀取域的值,編碼型別為UTF-8,若讀取失敗則返回null * @param fieldNum * @return */ public String getFieldStringValue(int fieldNum) { try { return getFieldStringValue(fieldNum, "UTF-8"); } catch (Exception e) { return null; } } /** * 以Int格式讀取域的值,若讀取失敗則返回-1 * @param fieldNum * @return */ public int getFieldIntValue(int fieldNum) { try { String str = this.getFieldStringValue(fieldNum); return Integer.parseInt(str); } catch (Exception e) { return -1; } } /** * 以byte[]格式讀取域的值(如果是LLVAR等變長欄位的話,則不包含長度位元組) * @param fieldNum * @return */ public byte[] getFieldBytesValue(int fieldNum) { byte[] bytes = this.getFieldBytesValueWithLength(fieldNum); Iso8583Package.Iso8583Field fieldConfig = iso8583FieldConfigs.get(new Integer(fieldNum)); // 域配置 if (bytes == null || fieldConfig == null) { return null; } Iso8583Package.FieldFormat fieldFormat = fieldConfig.getFieldFormat(); // 變長佔用的位元組數 int lengthBytesLength = this.getVarLengthBytesLength(fieldFormat); return ByteUtils.getSubBytesByIndex(bytes, lengthBytesLength, bytes.length - 1); } /** * 以byte[]格式讀取域的值(如果是LLVAR等變長欄位的話,包含長度位元組) * @param fieldNum * @return */ public byte[] getFieldBytesValueWithLength(int fieldNum) { return fieldsData.get(new Integer(fieldNum)); } /** * 刪除域(2~64/128) * @param fieldNum * @return */ public boolean deleteField(int fieldNum) { if (fieldNum < 2 || fieldNum > bitMapBytes.length * 8) { return false; } setBitMap(fieldNum, 0); this.fieldsData.remove(new Integer(fieldNum)); return true; } /** * 判斷是否存在域fieldNum * @param filedNum * @return */ public boolean existsField(int fieldNum) { try { if (fieldNum == 1) { return true; } String bitMapStr = ByteUtils.getBinaryString(bitMapBytes); return bitMapStr.charAt(fieldNum - 1) == '1'; } catch (Exception e) { return false; } } /** * 獲取所有域資訊(預設UTF-8編碼) * @return */ public String fieldsDataToString() { return fieldsDataToString("UTF-8"); } /** * 獲取所有域資訊 * @return */ public String fieldsDataToString(String charsetName) { StringBuffer result = new StringBuffer(); result.append("----------------------------------------------------------------------------------" + System.getProperty("line.separator")); //result.append("Fld:Field BytLen:BytesLength(位元組長度) LenByt:LengthBytes(變長長度位元組)" + System.getProperty("line.separator")); String bitMapStr = ByteUtils.getBinaryString(bitMapBytes); int bitMapStrLength = bitMapStr.length(); for (int i = 0; i < bitMapStrLength; i++) { if (bitMapStr.charAt(i) == '1' || i == 0) { result.append(fieldDataToString(i + 1, charsetName) + System.getProperty("line.separator")); } } result.append("----------------------------------------------------------------------------------"); return result.toString(); } /** * 獲取指定域資訊(預設UTF-8編碼) * @param fieldNum * @return */ public String fieldDataToString(int fieldNum) { return fieldDataToString(fieldNum, "UTF-8"); } /** * 獲取指定域資訊 * @param fieldNum * @return */ public String fieldDataToString(int fieldNum, String charsetName) { try { StringBuffer result = new StringBuffer(); Integer fieldNumInteger = fieldNum; result.append("[Fld: " + StringUtils.padLeft(fieldNumInteger + "", 2, ' ') + "]"); byte[] fieldData = fieldsData.get(fieldNumInteger); // 域位元組值 Iso8583Package.Iso8583Field fieldConfig = iso8583FieldConfigs.get(fieldNumInteger); // 域配置 Iso8583Package.FieldFormat fieldFormat = fieldConfig.getFieldFormat(); Iso8583Package.DataStorageFormat dataStorageFormat = fieldConfig.getDataStorageFormat(); // 變長佔用的位元組數 int lengthBytesLength = this.getVarLengthBytesLength(fieldFormat); result.append("[" + StringUtils.padLeft((dataStorageFormat + "").substring(0, 3), 3, ' ') + "]"); byte[] fieldContentData = new byte[] {}; // 除去變長部分後的位元組內容 if (lengthBytesLength > 0) { byte[] lengthBytes = ByteUtils.getSubBytesByIndex(fieldData, 0, lengthBytesLength - 1); String lengthBytesStr = ByteUtils.getHexString(lengthBytes); result.append("[MaxLen: " + StringUtils.padLeft(fieldConfig.getLength() + "", 3, ' ') + "]"); result.append("[BytLen: " + StringUtils.padLeft(fieldData.length - lengthBytesLength + "", 3, ' ') + "]"); result.append("[(HEX)" + ByteUtils.getHexString(fieldData) + "]"); result.append("[LenByt(HEX): " + lengthBytesStr + "(" + this.getVarLength(fieldNum) + ")]"); fieldContentData = ByteUtils.getSubBytesByIndex(fieldData, lengthBytesLength, fieldData.length - 1); } else { result.append("[FixLen: " + StringUtils.padLeft(fieldConfig.getLength() + "", 3, ' ') + "]"); result.append("[BytLen: " + StringUtils.padLeft(fieldData.length + "", 3, ' ') + "]"); result.append("[(HEX)" + ByteUtils.getHexString(fieldData) + "]"); fieldContentData = fieldData; } if (dataStorageFormat == Iso8583Package.DataStorageFormat.ASCII) { result.append("[(ASCII)" + new String(fieldContentData, charsetName) + "]"); } else if (dataStorageFormat == Iso8583Package.DataStorageFormat.BCD) { result.append("[(BCD)" + this.getFieldBCDValue(fieldNum) + "]"); } return result.toString(); } catch (Exception e) { return "獲取域資訊[Field: " + fieldNum + ", Charset: " + charsetName + "]失敗!" + e.getMessage() == null ? "" : e.getMessage(); } } /** * 獲取不定長欄位的長度部分位元組長 * @param fieldFormat * @return */ private int getVarLengthBytesLength(Iso8583Package.FieldFormat fieldFormat) { int lengthBytesLength = 0; // 變長佔用的位元組數 if (this.varLengthFormat == Iso8583Package.VarLengthFormat.BCD) { if (fieldFormat == Iso8583Package.FieldFormat.LVAR || fieldFormat == Iso8583Package.FieldFormat.LLVAR) { lengthBytesLength = 1; } else if (fieldFormat == Iso8583Package.FieldFormat.LLLVAR || fieldFormat == Iso8583Package.FieldFormat.LLLLVAR) { lengthBytesLength = 2; } } else if (this.varLengthFormat == Iso8583Package.VarLengthFormat.ASCII || this.varLengthFormat == Iso8583Package.VarLengthFormat.NUMBER_STRING) { if (fieldFormat == Iso8583Package.FieldFormat.LVAR) { lengthBytesLength = 1; } else if (fieldFormat == Iso8583Package.FieldFormat.LLVAR) { lengthBytesLength = 2; } else if (fieldFormat == Iso8583Package.FieldFormat.LLLVAR) { lengthBytesLength = 3; } else if (fieldFormat == Iso8583Package.FieldFormat.LLLLVAR) { lengthBytesLength = 4; } } return lengthBytesLength; } /** * 獲取不定長欄位的長度值(實際個數) * @param fieldNum * @return */ private int getVarLength(int fieldNum) { Iso8583Package.Iso8583Field fieldConfig = iso8583FieldConfigs.get(fieldNum); long varLength = 0; // 計算不定長實際個數 Iso8583Package.FieldFormat fieldFormat = fieldConfig.getFieldFormat(); if (fieldFormat != Iso8583Package.FieldFormat.NONE) { // 長度位元組數(LL..L 佔用的位元組數) int lengthBytesLength = this.getVarLengthBytesLength(fieldFormat); byte[] iso8583FieldBytes = this.getFieldBytesValueWithLength(fieldNum); if (this.varLengthFormat == Iso8583Package.VarLengthFormat.BCD) { varLength = ByteUtils.readBCD(iso8583FieldBytes, 0, lengthBytesLength); } else if (this.varLengthFormat == Iso8583Package.VarLengthFormat.ASCII) { varLength = ByteUtils.readLong(iso8583FieldBytes, 0, lengthBytesLength); } else if (this.varLengthFormat == Iso8583Package.VarLengthFormat.NUMBER_STRING) { varLength = Long.parseLong(ByteUtils.readString(iso8583FieldBytes, 0, lengthBytesLength)); } } return (int) varLength; } // getter setter /** * 報文總的內容, messageTypeBytes + iso8583FieldsBytes * @return */ public byte[] getTotalMessageBytes() { byte[] iso8583FieldsBytes = this.getIso8583FieldsBytes(); byte[] total = new byte[this.messageTypeBytes.length + iso8583FieldsBytes.length]; int idx = 0; for (int i = 0; i < this.messageTypeBytes.length; i++) { total[idx++] = this.messageTypeBytes[i]; } for (int i = 0; i < iso8583FieldsBytes.length; i++) { total[idx++] = iso8583FieldsBytes[i]; } return total; } /** * 獲取BCD編碼的訊息型別 * @return */ public String getMessageType() { return ByteUtils.getHexString(this.messageTypeBytes); } /** * messageType由2位元組組成 * @param messageType */ public void setMessageType(byte[] messageTypeBytes) { if (messageTypeBytes == null || messageTypeBytes.length != 2) { throw new RuntimeException("引數值[messageType: " + ByteUtils.getHexString(messageTypeBytes) + "]有誤!"); } this.messageTypeBytes = messageTypeBytes; } /** * messageType由[0-9/a-f/A-F]組成(2個位元組十六進位制表示) * @param messageType */ public void setMessageType(String messageType) { if (!RegularUtils.doMatch("[0-9a-fA-F]{4}", messageType)) { throw new RuntimeException("引數值[messageType: " + messageType + "]有誤!"); } this.messageTypeBytes = ByteUtils.hexStringToBytes(messageType); } /** * 獲取ISO8583域1-64/128位元組陣列 * @return */ public byte[] getIso8583FieldsBytes() { String resultStr = ""; String bitMapStr = ByteUtils.getBinaryString(bitMapBytes); int bitMapStrLength = bitMapStr.length(); for (int i = 0; i < bitMapStrLength; i++) { if (bitMapStr.charAt(i) == '1' || i == 0) { resultStr += ByteUtils.getHexString(this.fieldsData.get(new Integer(i + 1))); } } byte[] result = ByteUtils.hexStringToBytes(resultStr); return result == null ? new byte[0] : result; } /****************** 內部類 *******************************************/ // <!-- 說明 --> // <!-- <iso8583Field> --> // <!-- <fieldNum>域, 1-128</fieldNum> --> // <!-- <fieldName>域名稱</fieldName> --> // <!-- <dataStorageFormat>域資料儲存格式, ASCII碼格式儲存, BINARY格式儲存, BCD格式儲存</dataStorageFormat> --> // <!-- <length>長度</length> --> // <!-- <fieldFormat>域內容格式, None: 無, LVAR: 1個位元組BCD表示的長度位後面跟上這些長度的位元組, LLVAR: 1個位元組BCD長度位, LLLVAR: 2個位元組BCD長度位置, LLLLVAR: 2個位元組BCD長度位置</fieldFormat> --> // <!-- <align>資料對齊方式, Left, Right</align> --> // <!-- <padChar>填充字元, Null: 不填充, Space: 填充空格</padChar> --> // <!-- </iso8583Field> --> private class Iso8583Field { private int fieldNum; private String fieldName; private Iso8583Package.DataStorageFormat dataStorageFormat; private int length; private Iso8583Package.FieldFormat fieldFormat; private Iso8583Package.Align align; private Iso8583Package.PadChar padChar; public String toString() { return "fieldNum: " + fieldNum + ", fieldName: " + fieldName + ", dataStorageFormat: " + dataStorageFormat + ", length: " + length + ", fieldFormat: " + fieldFormat + ", align: " + align + ", padChar: " + padChar; } public int getFieldNum() { return fieldNum; } public void setFieldNum(int fieldNum) { this.fieldNum = fieldNum; } public String getFieldName() { return fieldName; } public void setFieldName(String fieldName) { this.fieldName = fieldName; } public Iso8583Package.DataStorageFormat getDataStorageFormat() { return dataStorageFormat; } public void setDataStorageFormat(Iso8583Package.DataStorageFormat dataStorageFormat) { this.dataStorageFormat = dataStorageFormat; } public int getLength() { return length; } public void setLength(int length) { this.length = length; } public Iso8583Package.FieldFormat getFieldFormat() { return fieldFormat; } public void setFieldFormat(Iso8583Package.FieldFormat fieldFormat) { this.fieldFormat = fieldFormat; } public Iso8583Package.Align getAlign() { return align; } public void setAlign(Iso8583Package.Align align) { this.align = align; } public Iso8583Package.PadChar getPadChar() { return padChar; } public void setPadChar(Iso8583Package.PadChar padChar) { this.padChar = padChar; } } /****************** 列舉定義 *******************************************/ /** * 資料儲存格式 */ public enum DataStorageFormat { ASCII, BCD, BINARY; } /** * 域內容格式 */ public enum FieldFormat { NONE, LVAR, LLVAR, LLLVAR, LLLLVAR; } /** * 資料對齊方式 */ public enum Align { LEFT, RIGHT; } /** * 填充字元 */ public enum PadChar { NULL, SPACE; } /** * 變長欄位的長度部分儲存格式<br> * BCD: 長度儲存格式為壓縮的BCD碼, LVAR和LLVAR長度佔用一個位元組, LLLVAR和LLLLVAR長度佔用兩個位元組.<br> * ASCII: 長度儲存格式為ASCII, LVAR長度佔用一個位元組, LLVAR佔用兩個位元組, LLLVAR佔用三個位元組, LLLLVAR佔用四個位元組.<br> * NUMBER_STRING: 長度儲存格式為數字字串, 位數為1-4位, 對應L-LLLL, 佔用位元組數同ASCII格式.<br> */ public enum VarLengthFormat { BCD, ASCII, NUMBER_STRING } }
2、配置檔案
<?xml version="1.0" encoding="utf-8"?>
<iso8583Fields xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- 說明 -->
<!-- <iso8583Field> -->
<!-- <fieldNum>域, 1-128</fieldNum> -->
<!-- <fieldName>域名稱</fieldName> -->
<!-- <dataStorageFormat>域資料儲存格式, ASCII: ASCII碼格式儲存, BINARY: 二進位制格式儲存, BCD: 壓縮的BCD格式儲存</dataStorageFormat> -->
<!-- <length>長度. 當dataStorageFormat為ASCII時, 表示位元組個數; 當dataStorageFormat為BINARY時, 表示位元組數; 當dataStorageFormat為BCD時, 表示BCD字元個數(位元組個數=BCD字元數/2)</length> -->
<!-- <fieldFormat>域內容格式, None: 無, LVAR: 1個位元組BCD表示的長度位(長度定義同length), LLVAR: 1個位元組BCD表示的長度位, LLLVAR: 2個位元組BCD表示的長度位置, LLLLVAR: 2個位元組BCD表示的長度位置</fieldFormat> -->
<!-- <align>資料對齊方式, Left, Right</align> -->
<!-- <padChar>填充字元, Null: 不填充, Space: 填充空格</padChar> -->
<!-- </iso8583Field> -->
<iso8583Field>
<fieldNum>1</fieldNum>
<fieldName>Bit Map</fieldName>
<dataStorageFormat>BINARY</dataStorageFormat>
<length>8</length>
<fieldFormat>None</fieldFormat>
<align>Left</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>2</fieldNum>
<fieldName>Primary Account Number</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>19</length>
<fieldFormat>LLVAR</fieldFormat>
<align>Left</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>3</fieldNum>
<fieldName>Processing Code</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>6</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>4</fieldNum>
<fieldName>Amount Transaction</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>12</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>5</fieldNum>
<fieldName>Transmission Date & Time</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>12</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>6</fieldNum>
<fieldName>System Trace Audit Number</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>12</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>7</fieldNum>
<fieldName>Time Local Transaction</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>14</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>8</fieldNum>
<fieldName>Date Local Transaction</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>8</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>9</fieldNum>
<fieldName>Point-of-Service Condition Code</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>8</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>10</fieldNum>
<fieldName>對帳流水號</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>8</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>11</fieldNum>
<fieldName>Acquiring Institution Identification Code</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>6</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>12</fieldNum>
<fieldName>Forwarding Institution Identofication Code</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>6</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>13</fieldNum>
<fieldName>Terminal Identification</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>8</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>14</fieldNum>
<fieldName>Identification Code</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>4</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>15</fieldNum>
<fieldName>Additional Data - National</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>4</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>16</fieldNum>
<fieldName>Additional Data - Private</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>4</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>17</fieldNum>
<fieldName>Security Related Control Information</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>4</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>18</fieldNum>
<fieldName>Account Identification 1</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>4</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>19</fieldNum>
<fieldName>扣款帳號</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>3</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>20</fieldNum>
<fieldName>Bit Map Extended</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>3</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>21</fieldNum>
<fieldName>Primary Account Number</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>3</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>22</fieldNum>
<fieldName>POINT OF SERVICE ENTRY MODE</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>3</length>
<fieldFormat>None</fieldFormat>
<align>Left</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>23</fieldNum>
<fieldName>Amount Transaction</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>3</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>24</fieldNum>
<fieldName>Transmission Date & Time</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>3</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>25</fieldNum>
<fieldName>POINT OF SERVICE CONDITION CODE</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>2</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>26</fieldNum>
<fieldName>POINT OF SERVICE PIN CAPTURE CODE</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>2</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>27</fieldNum>
<fieldName>Date Local Transaction</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>1</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>28</fieldNum>
<fieldName>Point-of-Service Condition Code</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>1</length>
<fieldFormat>None</fieldFormat>
<align>Left</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>29</fieldNum>
<fieldName>對帳流水號</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>8</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>30</fieldNum>
<fieldName>Acquiring Institution Identification Code</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>8</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>31</fieldNum>
<fieldName>Forwarding Institution Identofication Code</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>8</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>32</fieldNum>
<fieldName>Terminal Identification</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>11</length>
<fieldFormat>LLVAR</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>33</fieldNum>
<fieldName>Identification Code</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>11</length>
<fieldFormat>LLVAR</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>34</fieldNum>
<fieldName>Additional Data - National</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>28</length>
<fieldFormat>LLVAR</fieldFormat>
<align>Left</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>35</fieldNum>
<fieldName>Additional Data - Private</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>37</length>
<fieldFormat>LLVAR</fieldFormat>
<align>Left</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>36</fieldNum>
<fieldName>Security Related Control Information</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>104</length>
<fieldFormat>LLLVAR</fieldFormat>
<align>Left</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>37</fieldNum>
<fieldName>Account Identification 1</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>12</length>
<fieldFormat>None</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>38</fieldNum>
<fieldName>扣款帳號</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>6</length>
<fieldFormat>None</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>39</fieldNum>
<fieldName>Bit Map Extended</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>2</length>
<fieldFormat>None</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>40</fieldNum>
<fieldName>Primary Account Number</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>999</length>
<fieldFormat>LLLVAR</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>41</fieldNum>
<fieldName>Processing Code</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>15</length>
<fieldFormat>None</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>42</fieldNum>
<fieldName>Amount Transaction</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>12</length>
<fieldFormat>None</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>43</fieldNum>
<fieldName>Transmission Date & Time</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>40</length>
<fieldFormat>None</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>44</fieldNum>
<fieldName>System Trace Audit Number</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>99</length>
<fieldFormat>LLVAR</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>45</fieldNum>
<fieldName>Time Local Transaction</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>76</length>
<fieldFormat>LLVAR</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>46</fieldNum>
<fieldName>Date Local Transaction</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>999</length>
<fieldFormat>LLLVAR</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>47</fieldNum>
<fieldName>Point-of-Service Condition Code</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>999</length>
<fieldFormat>LLLVAR</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>48</fieldNum>
<fieldName>對帳流水號</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>9999</length>
<fieldFormat>LLLLVAR</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>49</fieldNum>
<fieldName>Acquiring Institution Identification Code</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>3</length>
<fieldFormat>None</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>50</fieldNum>
<fieldName>Forwarding Institution Identofication Code</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>3</length>
<fieldFormat>None</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>51</fieldNum>
<fieldName>Terminal Identification</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>3</length>
<fieldFormat>None</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>52</fieldNum>
<fieldName>Identification Code</fieldName>
<dataStorageFormat>BINARY</dataStorageFormat>
<length>8</length>
<fieldFormat>None</fieldFormat>
<align>Left</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>53</fieldNum>
<fieldName>Additional Data - National</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>16</length>
<fieldFormat>None</fieldFormat>
<align>Left</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>54</fieldNum>
<fieldName>Additional Data - Private</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>99</length>
<fieldFormat>LLVAR</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>55</fieldNum>
<fieldName>Security Related Control Information</fieldName>
<dataStorageFormat>BINARY</dataStorageFormat>
<length>9999</length>
<fieldFormat>LLLLVAR</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>56</fieldNum>
<fieldName>Account Identification 1</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>999</length>
<fieldFormat>LLLVAR</fieldFormat>
<align>Right</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>57</fieldNum>
<fieldName>扣款帳號</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>999</length>
<fieldFormat>LLLVAR</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>58</fieldNum>
<fieldName>Bit Map Extended</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>999</length>
<fieldFormat>LLLVAR</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>59</fieldNum>
<fieldName>Primary Account Number</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>999</length>
<fieldFormat>LLLVAR</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>60</fieldNum>
<fieldName>Processing Code</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>999</length>
<fieldFormat>LLLVAR</fieldFormat>
<align>Left</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>61</fieldNum>
<fieldName>Amount Transaction</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>999</length>
<fieldFormat>LLLVAR</fieldFormat>
<align>Left</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>62</fieldNum>
<fieldName>Transmission Date & Time</fieldName>
<dataStorageFormat>BINARY</dataStorageFormat>
<length>512</length>
<fieldFormat>LLLVAR</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>63</fieldNum>
<fieldName>System Trace Audit Number</fieldName>
<dataStorageFormat>ASCII</dataStorageFormat>
<length>999</length>
<fieldFormat>LLLVAR</fieldFormat>
<align>Left</align>
<padChar>Space</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>64</fieldNum>
<fieldName>Time Local Transaction</fieldName>
<dataStorageFormat>BINARY</dataStorageFormat>
<length>8</length>
<fieldFormat>None</fieldFormat>
<align>Left</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>65</fieldNum>
<fieldName>Date Local Transaction</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>8</length>
<fieldFormat>None</fieldFormat>
<align>Left</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>66</fieldNum>
<fieldName>Point-of-Service Condition Code</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>1</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>67</fieldNum>
<fieldName>對帳流水號</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>2</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>68</fieldNum>
<fieldName>Acquiring Institution Identification Code</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>3</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>69</fieldNum>
<fieldName>Forwarding Institution Identofication Code</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>3</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>70</fieldNum>
<fieldName>Terminal Identification</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>3</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>71</fieldNum>
<fieldName>Identification Code</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>4</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>72</fieldNum>
<fieldName>Additional Data - National</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>4</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>73</fieldNum>
<fieldName>Additional Data - Private</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>6</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>74</fieldNum>
<fieldName>Security Related Control Information</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>10</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>75</fieldNum>
<fieldName>Account Identification 1</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>10</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>76</fieldNum>
<fieldName>扣款帳號</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>10</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>77</fieldNum>
<fieldName>Bit Map Extended</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>10</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>78</fieldNum>
<fieldName>Primary Account Number</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>10</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>79</fieldNum>
<fieldName>Processing Code</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>10</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>80</fieldNum>
<fieldName>Amount Transaction</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>10</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>81</fieldNum>
<fieldName>Transmission Date & Time</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>10</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Null</padChar>
</iso8583Field>
<iso8583Field>
<fieldNum>82</fieldNum>
<fieldName>System Trace Audit Number</fieldName>
<dataStorageFormat>BCD</dataStorageFormat>
<length>12</length>
<fieldFormat>None</fieldFormat>
<align>Right</align>
<padChar>Nul