Кодирование переменной длины от int до 2 байтов - PullRequest
0 голосов
/ 11 июня 2018

Я реализую кодирование переменной длины и читаю википедию об этом.Вот что я нашел:

0x00000080  0x81 0x00

Это означает, что 0x80 int кодируется как 0x81 0x00 2 байта.Это то, что я не могу понять.Хорошо, следуя приведенному там алгоритму, мы имеем.

  1. Двоичный 0x80: 00000000 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

Что я пропустил?

1 Ответ

0 голосов
/ 11 июня 2018

Давайте рассмотрим алгоритм со страницы Википедии:

  1. Возьмем двоичное представление целого числа
  2. Разделим его на группы по 7 битов, группа с наибольшим значением будет иметьless
  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;
}

Вы можете увидеть, как он работает для примеров со страницы Википедии здесь , вы также можете подключить свои собственные значения и попробовать его онлайн.

...