Hello. We've been using thej8583 library for several years with good results. Thank you.
I'm generating a new "Table" within a bit 63 message and I can't get it to generate the length correctly. The table is basically a Alpha message with a numeric length header of 4 places. The length of the value I have is 90 characters, or 0090 which should be set to 2 bytes null and ASCII 'Z' Instead I'm getting null and some unprintable character that translates to -112.
The code is:
IsoValue v1 = new IsoValue(IsoType.NUMERIC, <an int="" variable="" equaling="" 90="">, 4);
IsoValue v2 = new IsoValue(IsoType.ALPHA, "SP", 2);
IsoValue v3 = new IsoValue(IsoType.ALPHA, "01", 2);
...etc...
ByteArrayOutputStream bout = new ByteArrayOutputStream();
The Bit 63 message has several of these "Tables" in the same format and the rest all work fine. There is no difference in my code generating the tables. The only difference is this item is longer than the others, which max out at 48 characters.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm sorry but I don't know what you mean by "bit 63". Also I don't understand what you mean by "alpha message with a numeric length header of 4 places".
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Bit 63 = Field 63. It's an LLLVAR fields that takes data which consists of one or more "tables" which themselves each consist of a 2 byte (4 digit) numeric length followed by their text.
I've been able to determine the basic problem is we're ultimately sending these numeric length indicators within the table as HEX and not Binary.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
IsoValue v1 = new IsoValue(IsoType.NUMERIC, 48, 4);
IsoValue v2 = new IsoValue(IsoType.ALPHA, tableId, 4);
//etc
//now write the values to a stream, in binary format
ByteArrayOutputStream bout = new ByteArrayOutputStream();
v1.write(bout, true);
v2.write(bout, true);
//etc
String s = new String(bout.toByteArray());
//then you put this string inside a field in your message
When I put this String s to the message field, it's no longer BCD but Hex, and we're sending Hex to the processor.
To clarify, that hex is all of field 63 with one table item included. The total length of the field is 92 in 2 bytes, then the length of the table item should be 90 in 2 bytes, followed by the table text.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I think I may have narrowed my issue down a little more. When I use the IsoValue.write() method to write the length value to the output stream I'm getting the character I would expect, for example '...' for 85, but it's actually writing -123 to the byte array and sending 8230 in the message field.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I know exactly what is going wrong. If the length of the table value goes over 79 into extended ASCII the write method is not encoding it correctly. Instead it starts using negative numbers and counting backwards so 80 becomes -128, 81 becomes -127 etc.
Specifically the error comes up in Bcd.encode on this line:
And this happens with binary messages, right? LLVAR or LLBIN I suppose?
The problem arises because the byte type in Java goes from -128 to 127. The line you refer to works with digits only, so that "99" becomes 0x99 for example. I'll add tests for encoding values above 79 as you mention just to be sure though.
BTW I'm really hosting the project on github now (it's been there for a couple of years now) so feel free to open an issue there. github.com/chochos/j8583
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello. We've been using thej8583 library for several years with good results. Thank you.
I'm generating a new "Table" within a bit 63 message and I can't get it to generate the length correctly. The table is basically a Alpha message with a numeric length header of 4 places. The length of the value I have is 90 characters, or 0090 which should be set to 2 bytes null and ASCII 'Z' Instead I'm getting null and some unprintable character that translates to -112.
The code is:
IsoValue v1 = new IsoValue(IsoType.NUMERIC, <an int="" variable="" equaling="" 90="">, 4);
IsoValue v2 = new IsoValue(IsoType.ALPHA, "SP", 2);
IsoValue v3 = new IsoValue(IsoType.ALPHA, "01", 2);
...etc...
ByteArrayOutputStream bout = new ByteArrayOutputStream();
v1.write(bout, true, false);
v1.write(bout, true, false);
v2.write(bout, true, false);
...etc...
The Bit 63 message has several of these "Tables" in the same format and the rest all work fine. There is no difference in my code generating the tables. The only difference is this item is longer than the others, which max out at 48 characters.
I'm sorry but I don't know what you mean by "bit 63". Also I don't understand what you mean by "alpha message with a numeric length header of 4 places".
Bit 63 = Field 63. It's an LLLVAR fields that takes data which consists of one or more "tables" which themselves each consist of a 2 byte (4 digit) numeric length followed by their text.
I've been able to determine the basic problem is we're ultimately sending these numeric length indicators within the table as HEX and not Binary.
e.g. we're sending ASCII H = HEX 48 = Binary 72 where we want to send ASCII 0 = HEX 30 = Binary 48.
Our processor doesn't care if we're sending binary or hex, all they see are the digits.
Maybe you should use LLLBIN instead of LLLVAR then. LLLBIN is used to contain binary data (a byte buffer).
I tried that with no luck. I worked with you on formatting this field a few years ago, thee is a message thread here:
https://sourceforge.net/p/j8583/discussion/689418/thread/bc6e0957/
IsoValue v1 = new IsoValue(IsoType.NUMERIC, 48, 4);
IsoValue v2 = new IsoValue(IsoType.ALPHA, tableId, 4);
//etc
//now write the values to a stream, in binary format
ByteArrayOutputStream bout = new ByteArrayOutputStream();
v1.write(bout, true);
v2.write(bout, true);
//etc
String s = new String(bout.toByteArray());
//then you put this string inside a field in your message
When I put this String s to the message field, it's no longer BCD but Hex, and we're sending Hex to the processor.
As a hex dump, this is what they're seeing:
00 92 00 5A 53 50 30 31 30
30 31 31 30 32 30 30 31 32 30 33 30 30 31 32 30
34 30 31 31 4E 49 53 43 31 3B 4E 49 53 43 31 30
35 30 34 30 3B 35 31 35 31 31 31 34 37 36 35 38
30 30 30 39 3D 36 31 30 31 39 30 33 38 39 35 39
38 32 38 36 33 32 30 37 31 31 3F 37 30 36 30 30
34 4C 41 4B 39
This is what they expect:
00 92 00 90 ... rest is the same
Apparently they expect the length header within the field 63 message to be in decimal but the rest in Hex.
To clarify, that hex is all of field 63 with one table item included. The total length of the field is 92 in 2 bytes, then the length of the table item should be 90 in 2 bytes, followed by the table text.
I think I may have narrowed my issue down a little more. When I use the IsoValue.write() method to write the length value to the output stream I'm getting the character I would expect, for example '...' for 85, but it's actually writing -123 to the byte array and sending 8230 in the message field.
It's blowing up if the hex code for the length length goes into extended ASCII. Up to 79 it works fine but 80 and above breaks.
I know exactly what is going wrong. If the length of the table value goes over 79 into extended ASCII the write method is not encoding it correctly. Instead it starts using negative numbers and counting backwards so 80 becomes -128, 81 becomes -127 etc.
Specifically the error comes up in Bcd.encode on this line:
And this happens with binary messages, right? LLVAR or LLBIN I suppose?
The problem arises because the byte type in Java goes from -128 to 127. The line you refer to works with digits only, so that "99" becomes 0x99 for example. I'll add tests for encoding values above 79 as you mention just to be sure though.
BTW I'm really hosting the project on github now (it's been there for a couple of years now) so feel free to open an issue there. github.com/chochos/j8583
Yes, binary LLLVAR in my case. Thanks.
I just added BCD tests to the project and they pass, both encoding and decoding.
https://github.com/chochos/j8583/blob/master/src/test/java/j8583/TestBcd.java
I think you are confusing hex with decimal. BCD encodes the decimal number 99 as 0x99, which is decimal 153.