Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:将字符串转换为压缩十进制_Java_Byte_Ascii_Ibm Midrange_Ebcdic - Fatal编程技术网

Java:将字符串转换为压缩十进制

Java:将字符串转换为压缩十进制,java,byte,ascii,ibm-midrange,ebcdic,Java,Byte,Ascii,Ibm Midrange,Ebcdic,新来的 情况: 我正在从事一个需要与AS/400服务器通信的项目。我的任务基本上是处理发送到AS/400服务器的请求。为此,所有用户输入都应以EDCDIC字节为单位 问题: 我已成功地使用以下代码将压缩小数转换为字符串,发现: public类PackedDecimal{ 公共静态长解析(字节[]pdIn)引发异常{ //将压缩小数转换为长小数 final int PlusSign=0x0C;//加号 final int MinusSign=0x0D;//减号 final int NoSign=0

新来的

情况: 我正在从事一个需要与AS/400服务器通信的项目。我的任务基本上是处理发送到AS/400服务器的请求。为此,所有用户输入都应以EDCDIC字节为单位

问题:
我已成功地使用以下代码将压缩小数转换为字符串,发现:

public类PackedDecimal{
公共静态长解析(字节[]pdIn)引发异常{
//将压缩小数转换为长小数
final int PlusSign=0x0C;//加号
final int MinusSign=0x0D;//减号
final int NoSign=0x0F;//未签名
final int DropHO=0xFF;//和用于丢弃HO符号位的掩码
final int GetLO=0x0F;//仅获取LO位
long val=0;//要返回的值
对于(int i=0;i>4;//第一个获取数字
val=val*10+位;
//System.out.println(“digit=“+digit+”,val=“+val”);
int sign=aByte&GetLO;//现在获取符号
如果(符号==最小符号)
val=-val;
否则{
//我们是否关心是否有无效标志?
if(sign!=PlusSign&&sign!=NoSign)
抛出新异常(“OC7”);
}
}否则{
int digit=aByte>>4;//HO优先
val=val*10+位;
//System.out.println(“digit=“+digit+”,val=“+val”);
digit=aByte&GetLO;//现在是LO
val=val*10+位;
//System.out.println(“digit=“+digit+”,val=“+val”);
}
}
返回val;
}//end parse()
//测试上述内容
公共静态void main(字符串[]args)引发异常{
byte[]pd=新字节[]{0x19,0x2C};//192
System.out.println(PackedDecimal.parse(pd));
pd=新字节[]{(字节)0x98、0x44、0x32、0x3D};//-9844323
System.out.println(PackedDecimal.parse(pd));
pd=新字节[]{(字节)0x98、0x44、0x32};//符号无效
System.out.println(PackedDecimal.parse(pd));
}
}
我现在的问题是,我必须将这些字符串值再次转换为EBCDIC字节,以便AS/400服务器能够理解它。我计划使用Silverlake文档中指定的格式构造一个请求(原始字节)。一旦构建了请求,我计划使用一个POJO手动更改该请求中的值,该POJO存储我的请求(带有setter和getter),这样我就可以像
request.setField1(“Stuff”.getBytes(Charset.forName(“Cp1047”))

我对比特、字节和半字节没有那么多经验。我希望有人能帮助我


在我们的代码中,我们发现了一个压缩的十进制数,它由5个字节组成。它有点像={000f}。我使用从上面代码中得到的方法来转换它,得到的值是0。现在,我想将0转换回其原始形式,其原始字节大小为5。

该库提供的类正是用于此目的。

这是我的长到压缩十进制方法版本

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();
    }

}

我遇到了一个类似的问题

该类构成了解码/解析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();
    }
}

尽情享受吧

这是我的简单解决方案:它将字符串转换为正压缩数

实用程序类:

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
结果:

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

您希望压缩的十进制数像您的输入一样作为字节数组,还是希望实际的n个字节作为实际的压缩十进制数,哪一个是Java中的字符串?@GilbertLeBlanc:我希望输出也是一个字节数组,因为我将把它传递给as/400服务器。我真的不明白您是如何尝试与as/400通信的。我不完全确定压缩小数,但到目前为止,我可以避免在java或php和as/400之间进行通信时,使用诸如ILE调用或SQL之类的东西进行位/字节操作,甚至避免一些代码页问题。你如何把你的信息放在as/400上?我团队中的一些人已经在做这个了。我的小组被指派在不使用JTOpen和IBM工具箱等的情况下完成这项工作:PI将尝试一下。谢谢您的回复:)哦,顺便问一下,如果没有
int bytes
参数,这可能吗?我的意思是,我是否可以从转换后的字符串本身检索字节数组大小?@Miguel-pulation:可以,但IBM计算机上通常压缩的十进制字段大小固定,与内容无关。压缩十进制字段几乎总是偶数字节。@GilbertLeBlanc:在byteToString方法中,示例代码使用0x加字节整数值的表示法。0x通常表示十六进制值,因此任何大于9的值都会产生误导(例如,输出中的0x13和0x15不正确)。将第二个append更改为sb.append(Integer.toHexString(b[i]);更合适。@jr:你说得对。我不记得三年前我在想什么。谢谢道奇。如何将十进制数(带浮点值)转换为COBOL字节数组,反之亦然?@HaMi对不起,我不知道。而且我已经很久没有谈这个话题了。