int的可变长度编码为2个字节

时间:2018-06-11 13:41:26

标签: java int byte primitive

我正在实施变量长度编码并阅读wikipedia。这是我发现的:

0x00000080  0x81 0x00

意味着0x80 int被编码为0x81 0x00 2个字节。那是我无法理解的。好的,按照那里列出的算法我们有。

  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 。我试着写一个程序:

    callback url
  3. ideone

    我错过了什么?

2 个答案:

答案 0 :(得分:2)

存在另一种整数的可变长度编码,并且被广泛使用。例如,1984年的ASN.1将define "length" field设置为:

长度的编码可以采用两种形式:短或长。短 形式是一个单字节,介于0到127之间。

长格式的长度至少为两个字节,并且第一个字节的第8位 字节设置为1。第一个字节的位7-1指示还有多少个字节 在长度字段本身中。然后其余字节指定 长度本身,为多字节整数。

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

答案 1 :(得分:1)

让我们从维基百科页面查看算法:

  1. 获取整数的二进制表示
  2. 将其拆分为7位组,具有最高值的组将具有更少的
  3. 将这七位作为一个字节,将除最后一位之外的所有MSB(最高有效位)设置为1;留下0为最后一个
  4. 我们可以实现这样的算法:

    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中的示例,您也可以插入自己的值并在线尝试。

相关问题