有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java变量将int编码延长到2字节

我正在实现可变长度编码并阅读有关它的wikipedia。以下是我的发现:

0x00000080  0x81 0x00

这意味着0x80int被编码为0x81 0x002字节。这是我无法理解的。好的,按照上面列出的算法

  1. 二进制0x8000000000 00000000 00000000 10000000
  2. 我们将符号位移动到下一个八位字节,因此我们有并设置为1(表示我们有更多的八位字节): 00000000 00000000 00000001 10000000,它不等于0x81 0x00。我试图为此编写一个程序:

    byte[] ba = new byte[]{(byte) 0x81, (byte) 0x00};
    int first = (ba[0] & 0xFF) & 0x7F;
    int second = ((ba[1] & 0xFF) & 0x7F) << 7;
    int result = first | second;
    System.out.println(result); //prints 1, not 0x80
    

ideone

我错过了什么


共 (2) 个答案

  1. # 1 楼答案

    整数的另一种可变长度编码存在并被广泛使用。例如ASN。1从1984年起define "length" field作为:

    The encoding of length can take two forms: short or long. The short form is a single byte, between 0 and 127.

    The long form is at least two bytes long, and has bit 8 of the first byte set to 1. Bits 7-1 of the first byte indicate how many more bytes are in the length field itself. Then the remaining bytes specify the length itself, as a multi-byte integer.

    例如,在DLMS COSEM协议或https证书中使用此编码。对于简单的代码,您可以查看ASN.1 java library

  2. # 2 楼答案

    让我们回顾一下维基百科页面上的算法:

    1. 取整数的二进制表示形式
    2. 将其拆分为7位的组,具有最高值的组将具有较少的
    3. 将这七位作为一个字节,将除最后一位以外的所有位的MSB(最高有效位)设置为1;留0作为最后一个

    我们可以实现如下算法:

    public static byte[] variableLengthInteger(int input) {
        // first find out how many bytes we need to represent the integer
        int numBytes = ((32 - Integer.numberOfLeadingZeros(input)) + 6) / 7;
        // if the integer is 0, we still need 1 byte
        numBytes = numBytes > 0 ? numBytes : 1;
        byte[] output = new byte[numBytes];
        // for each byte of output ...
        for(int i = 0; i < numBytes; i++) {
            // ... take the least significant 7 bits of input and set the MSB to 1 ...
            output[i] = (byte) ((input & 0b1111111) | 0b10000000);
            // ... shift the input right by 7 places, discarding the 7 bits we just used
            input >>= 7;
        }
        // finally reset the MSB on the last byte
        output[0] &= 0b01111111; 
        return output;
    }
    

    您可以在维基百科页面here上看到它对示例有效,您也可以插入自己的值并在线尝试