代码之家  ›  专栏  ›  技术社区  ›  dtb

将整数编码为可变长度的big endian字节数组

  •  1
  • dtb  · 技术社区  · 15 年前

    我需要将一个整数写入一个字节数组,这样开头的零将被省略,字节将以大尾数顺序写入。

    例子:

    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 回复  |  直到 15 年前
        1
  •  3
  •   dtb    15 年前

    根据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,则此版本不会写入任何内容。

        2
  •  3
  •   Pavel Radzivilovsky    15 年前
    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;
    }
    
        3
  •  0
  •   x77    15 年前

    请注意,您正在将值保存到可变长度字节数组中。如果保存这些字节数组,还需要保存长度。

    您可以从BinaryWriter看到受保护的函数write7bitencodent,从BinaryReader看到read7bitencodent。

    这些函数将存储空间保存在磁盘上,以存储正数。数字0-128只需要一个字节。

    当保存到流时,Microsoft使用这些函数来存储/检索字符串长度前缀。

    要使用这些函数,可以创建从BinaryReader/BinaryWriter派生的自己的类。