Кодировать целое число как байтовый массив с переменной длиной байта - PullRequest
1 голос
/ 05 июля 2010

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

Пример:

int    original = 0x00123456;

byte[] encoded  = Encode(original);  //  == new byte[] { 0x12, 0x34, 0x56 };

int    decoded  = Decode(encoded);   //  == 0x123456

Мой Decode метод:

private static int Decode(byte[] buffer, int index, int length)
{
    int result = 0;
    while (length > 0)
    {
        result = (result << 8) | buffer[index];
        index++;
        length--;
    }
    return result;
}

Я изо всех сил пытаюсь придумать метод Encode, который не требует временного буфера или обращает байты после записи их в порядке байтов. Кто-нибудь может помочь?

private static int Encode(int value, byte[] buffer, int index)
{

}

Ответы [ 3 ]

3 голосов
/ 05 июля 2010

В соответствии с запросом OP, здесь есть версия без циклов для 32-разрядного числа:

private static int Encode(int value, byte[] buffer, int index)
{
    byte temp;
    bool leading = true;

    temp = (value >> 24) & 0xFF;
    if (temp > 0) {
      buffer[index++] = temp;
      leading = false;
    }

    temp = (value >> 16) & 0xFF;
    if (temp > 0 || leading == false) {
      buffer[index++] = temp;
      leading = false;
    }

    temp = (value >> 8) & 0xFF;
    if (temp > 0 || leading == false) {
      buffer[index++] = temp;
      leading = false;
    }

    temp = value & 0xFF;
    buffer[index++] = temp;

    return index;
}

Версия с использованием цикла для 32-разрядных чисел:

private static int Encode(int value, byte[] buffer, int index)
{
    int length = 0;

    for (int i = 3; i >= 0; i++) {
      byte temp = (byte)(value >> (8 * i));
      if (temp > 0 || length > 0) {
        buffer[index++] = temp;
        length++;
      }
    }

    return length;
}

Примечаниечто эта версия ничего не пишет, если ввод просто 0.

3 голосов
/ 05 июля 2010
private static int Encode(int value, byte[] buffer, int index)
{
    int length = 0;
    int valueCopy = value;
    while (valueCopy != 0)
    {
        valueCopy >>= 8;
        length++;
    }
    for (int i = 0; i < length; i++)
    {
        buffer[index + length - i - 1] = (byte)value;
        value >>= 8;
    }
    return length;
}
0 голосов
/ 05 июля 2010

Обратите внимание, что вы сохраняете значение в массив байтов переменной длины.Если вы сохраните эти byteArray, вам также потребуется сохранить длину.

Вы можете увидеть защищенные функции Write7BitEncodedInt из BinaryWriter и Read7BitEncodedInt из BinaryReader.

Эти функции сохраняют память на диске для положительных чисел.Для числа 0-128 требуется только один байт.

Microsoft использует эти функции для сохранения / получения префикса длины строки при сохранении в Stream.

Чтобы использовать эти функции, вы можете создать собственный производный классот BinaryReader / BinaryWriter.

...