新来的!
情况: 我正在开发一个需要与AS / 400服务器通信的项目。我的任务是基本上处理将发送到AS / 400服务器的请求。为此,所有用户输入都应该是EDCDIC字节。
问题:
我已设法使用下面的代码将压缩小数转换为String,找到on this forum:
public class PackedDecimal {
public static long parse(byte[] pdIn) throws Exception {
// Convert packed decimal to long
final int PlusSign = 0x0C; // Plus sign
final int MinusSign = 0x0D; // Minus
final int NoSign = 0x0F; // Unsigned
final int DropHO = 0xFF; // AND mask to drop HO sign bits
final int GetLO = 0x0F; // Get only LO digit
long val = 0; // Value to return
for (int i = 0; i < pdIn.length; i++) {
int aByte = pdIn[i] & DropHO; // Get next 2 digits & drop sign bits
if (i == pdIn.length - 1) { // last digit?
int digit = aByte >> 4; // First get digit
val = val * 10 + digit;
// System.out.println("digit=" + digit + ", val=" + val);
int sign = aByte & GetLO; // now get sign
if (sign == MinusSign)
val = -val;
else {
// Do we care if there is an invalid sign?
if (sign != PlusSign && sign != NoSign)
throw new Exception("OC7");
}
} else {
int digit = aByte >> 4; // HO first
val = val * 10 + digit;
// System.out.println("digit=" + digit + ", val=" + val);
digit = aByte & GetLO; // now LO
val = val * 10 + digit;
// System.out.println("digit=" + digit + ", val=" + val);
}
}
return val;
} // end parse()
// Test the above
public static void main(String[] args) throws Exception {
byte[] pd = new byte[] { 0x19, 0x2C }; // 192
System.out.println(PackedDecimal.parse(pd));
pd = new byte[] { (byte) 0x98, 0x44, 0x32, 0x3D }; // -9844323
System.out.println(PackedDecimal.parse(pd));
pd = new byte[] { (byte) 0x98, 0x44, 0x32 }; // invalid sign
System.out.println(PackedDecimal.parse(pd));
}
}
我现在的问题是我必须将这些String值再次转换为EBCDIC字节,以便AS / 400服务器能够理解它。我打算使用Silverlake文档中指定的格式来构建请求(原始字节)。一旦构建了请求,我计划使用存储我的请求的POJO手动更改该请求中的值(使用setter和getter),这样我就可以像request.setField1("Stuff".getBytes(Charset.forName("Cp1047")))
一样。
我对位,字节和半字节没有太多经验。我希望有人可以帮助我。
在我们的代码中,我们发现了一个由5个字节组成的压缩十进制数。它类似于= {00 00 00 00 0F}。我使用从上面的代码获得的方法转换它,我得到的值是0.现在,我想将此0转换回其原始字节大小为5的原始形式。
答案 0 :(得分:4)
答案 1 :(得分:2)
这是我的一个长整数十进制方法的版本。
public class PackedDecimal {
public static byte[] format(long number, int bytes) {
byte[] b = new byte[bytes];
final byte minusSign = 0x0D; // Minus
final byte noSign = 0x0F; // Unsigned
String s = Long.toString(number);
int length = s.length();
boolean isNegative = false;
if (s.charAt(0) == '-') {
isNegative = true;
s = s.substring(1);
length--;
}
int extraBytes = length - bytes + 1;
if (extraBytes < 0) {
// Pad extra byte positions with zero
for (int i = 0; i < -extraBytes; i++) {
b[i] = 0x00;
}
} else if (extraBytes > 0) {
// Truncate the high order digits of the number to fit
s = s.substring(extraBytes);
length -= extraBytes;
extraBytes = 0;
}
// Translate the string digits into bytes
for (int i = 0; i < length; i++) {
String digit = s.substring(i, i + 1);
b[i - extraBytes] = Byte.valueOf(digit);
}
// Add the sign byte
if (isNegative) {
b[bytes - 1] = minusSign;
} else {
b[bytes - 1] = noSign;
}
return b;
}
public static void main(String[] args) {
long number = -456L;
byte[] b = PackedDecimal.format(number, 5);
System.out.println("Number: " + number + ", packed: " + byteToString(b));
number = 0L;
b = PackedDecimal.format(number, 5);
System.out.println("Number: " + number + ", packed: " + byteToString(b));
number = 5823L;
b = PackedDecimal.format(number, 5);
System.out.println("Number: " + number + ", packed: " + byteToString(b));
number = 123456L;
b = PackedDecimal.format(number, 5);
System.out.println("Number: " + number + ", packed: " + byteToString(b));
}
public static String byteToString(byte[] b) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < b.length; i++) {
sb.append("0x");
sb.append(Integer.toHexString((int) b[i]).toUpperCase());
sb.append(" ");
}
return sb.toString();
}
}
以下是测试结果。
Number: -456, packed: 0x0 0x4 0x5 0x6 0xD
Number: 0, packed: 0x0 0x0 0x0 0x0 0xF
Number: 5823, packed: 0x5 0x8 0x2 0x3 0xF
Number: 123456, packed: 0x3 0x4 0x5 0x6 0xF
答案 2 :(得分:1)
我遇到了类似的问题...
该类构成解码/解析PackedDecimals的第一篇文章工作得很好......但Gilbert Le Blancs的代码答案没有产生有效的输出。
所以我修理了他的代码......
public class PackedDecimal {
private static final int PlusSign = 0x0C; // Plus sign
private static final int MinusSign = 0x0D; // Minus
private static final int NoSign = 0x0F; // Unsigned
private static final int DropHO = 0xFF; // AND mask to drop HO sign bits
private static final int GetLO = 0x0F; // Get only LO digit
public static long parse(byte[] pdIn) throws Exception {
long val = 0; // Value to return
for (int i = 0; i < pdIn.length; i++) {
int aByte = pdIn[i] & DropHO; // Get next 2 digits & drop sign bits
if (i == pdIn.length - 1) { // last digit?
int digit = aByte >> 4; // First get digit
val = val * 10 + digit;
log("digit=" + digit + ", val=" + val);
int sign = aByte & GetLO; // now get sign
if (sign == MinusSign)
val = -val;
else {
// Do we care if there is an invalid sign?
if (sign != PlusSign && sign != NoSign) {
System.out.println();
for (int x = 0; x < pdIn.length; x++) {
System.out.print(Integer.toString(pdIn[x] & 0x000000ff, 16));
}
System.out.println();
throw new Exception("OC7");
}
}
} else {
int digit = aByte >> 4; // HO first
val = val * 10 + digit;
log("digit=" + digit + ", val=" + val);
digit = aByte & GetLO; // now LO
val = val * 10 + digit;
log("digit=" + digit + ", val=" + val);
}
}
return val;
}
public static byte[] format(long number, int byteCount) {
byte[] bytes = new byte[byteCount];
String data = Long.toString(number);
int length = data.length();
boolean isNegative = false;
if (data.charAt(0) == '-') {
isNegative = true;
data = data.substring(1);
length--;
}
if (length % 2 == 0) {
data = "0" + data;
length++;
}
int neededBytes = (int) (((length + 1) / 2f) + 0.5f);
int extraBytes = neededBytes - byteCount;
if (extraBytes < 0) {
// Pad extra byte positions with zero
for (int i = 0; i < -extraBytes; i++) {
bytes[i] = 0x00;
}
} else if (extraBytes > 0) {
// Truncate the high order digits of the number to fit
data = data.substring(extraBytes);
length -= extraBytes;
extraBytes = 0;
}
// Translate the string digits into bytes
for (int pos = 0; pos <= length - 1; pos++) {
String digit = data.substring(pos, pos + 1);
int now = (pos / 2) - extraBytes;
if (pos % 2 == 0) { // High
bytes[now] = (byte) (Byte.valueOf(digit) << 4);
log("HIGH " + digit);
} else { // Low
bytes[now] = (byte) (bytes[now] | (Byte.valueOf(digit) & 0x0f));
log("LOW " + digit);
}
}
// Add the sign byte
if (isNegative) {
bytes[byteCount - 1] = (byte) (bytes[byteCount - 1] | MinusSign);
} else {
bytes[byteCount - 1] = (byte) (bytes[byteCount - 1] | PlusSign);
}
return bytes;
}
private static void log(String string) {
// System.out.println(string);
}
public static void main(String[] args) throws Exception {
long price;
byte[] format;
price = 44981;
format = PackedDecimal.format(price, 5);
System.out.println("Input: " + price);
System.out.println("Bytes: " + byteToString(format));
System.out.println("Result: " + PackedDecimal.parse(format));
System.out.println("---------");
price = 4498;
format = PackedDecimal.format(price, 4);
System.out.println("Input: " + price);
System.out.println("Bytes: " + byteToString(format));
System.out.println("Result: " + PackedDecimal.parse(format));
System.out.println("---------");
price = 1337;
format = PackedDecimal.format(price, 3);
System.out.println("Input: " + price);
System.out.println("Bytes: " + byteToString(format));
System.out.println("Result: " + PackedDecimal.parse(format));
System.out.println("---------");
}
public static String byteToString(byte[] b) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < b.length; i++) {
int curByte = b[i] & 0xFF;
sb.append("0x");
if (curByte <= 0x0F) {
sb.append("0");
}
sb.append(Integer.toString(curByte, 16));
sb.append(" ");
}
return sb.toString().trim();
}
}
结果:
Input: 44981
Bytes: 0x00 0x00 0x44 0x98 0x1c
Result: 44981
---------
Input: 4498
Bytes: 0x00 0x04 0x49 0x8c
Result: 4498
---------
Input: 1337
Bytes: 0x01 0x33 0x7c
Result: 1337
---------
玩得开心享受
答案 3 :(得分:0)
这是我的简单解决方案:它将String转换为正包装数字。
公用事业类:
public class StringToPacked {
public static byte[] stringToPacked(String number){
int length = number.length();
int remainder = length % 2;
if(remainder==0)number ="0" + number;
int quo = length / 2;
byte result[] = new byte[quo+1];
for(int i=0,j=0;i<quo;i++,j=j+2){
int a = Integer.parseInt(number.substring(j,j+1));
int b = Integer.parseInt(number.substring(j+1,j+2));
a = a<<4;
int c = a|b;
result[i]=(byte)c;
}
int a = Integer.parseInt(number.substring(number.length()-1,number.length()));
a = a<<4;
int b = 12;
int c = a|b;
result[quo]=(byte)c;
return result;
}
public static String displayHex(byte number[]){
char array[] ="0123456789ABCDF".toCharArray();
char result[]=new char[2*number.length];
for(int i=0;i<number.length;i++){
result[2*i]=array[number[i]>>4 & 0x0f];
result[2*i+1]=array[number[i] & 0x0f];
}
String okay = new String(result);
return okay;
}
}
主要类别:
public class Packedtest {
public static void main(String[] args) {
// TODO Auto-generated method stub
String number = "123456";
System.out.println(StringToPacked.stringToPacked(number));
byte b1[]=StringToPacked.stringToPacked(number);
String C1 =StringToPacked.displayHex(b1);
System.out.println(number);
System.out.println(C1);
number = "12";
System.out.println(StringToPacked.stringToPacked(number));
b1=StringToPacked.stringToPacked(number);
C1 =StringToPacked.displayHex(b1);
System.out.println(number);
System.out.println(C1);
number = "123";
System.out.println(StringToPacked.stringToPacked(number));
b1=StringToPacked.stringToPacked(number);
C1 =StringToPacked.displayHex(b1);
System.out.println(number);
System.out.println(C1);
number = "1234567";
System.out.println(StringToPacked.stringToPacked(number));
b1=StringToPacked.stringToPacked(number);
C1 =StringToPacked.displayHex(b1);
System.out.println(number);
System.out.println(C1);
number = "12345678";
System.out.println(StringToPacked.stringToPacked(number));
b1=StringToPacked.stringToPacked(number);
C1 =StringToPacked.displayHex(b1);
System.out.println(number);
System.out.println(C1);
}
结果:
[B@19e0bfd
123456
0123456C
[B@139a55
12
012C
[B@1db9742
123
123C
[B@106d69c
1234567
1234567C
[B@52e922
12345678
012345678C