简体   繁体   English

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

[英]Encode integer as variable-length big-endian byte-array

I need to write an integer to a byte array such that leading zeros are omitted and the bytes are written in big endian order. 我需要将一个整数写入字节数组,以便省略前导零,并且以大端顺序写入字节。

Example: 例:

int    original = 0x00123456;

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

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

My Decode method: 我的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;
}

I'm struggling to come up with an Encode method that doesn't require a temporary buffer or reverses the bytes after writing them in little endian order. 我正在努力提出一种Encode方法,该方法不需要临时缓冲区或在以小尾数顺序写入它们之后反转字节。 Can anyone help? 有人可以帮忙吗?

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

}
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;
}

As per OP's request, here is a version without loops for a 32-bit number: 根据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;
}

Version using a loop for 32-bit numbers: 使用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;
}

Note that this version doesn't write anything if the input is just 0. 请注意,如果输入仅为0,则此版本不写任何内容。

Note that you are saving the value to a variable Length byte array. 请注意,您正在将该值保存到可变的Length字节数组中。 If you save these byteArray, you need save also the length. 如果保存这些byteArray,则还需要保存长度。

You can see the protected Functions Write7BitEncodedInt from BinaryWriter and Read7BitEncodedInt from BinaryReader. 您可以从BinaryWriter中看到受保护的函数Write7BitEncodedInt,从BinaryReader中看到Read7BitEncodedInt。

These functions save storage on disk for positive numbers. 这些功能将磁盘上的存储空间保存为正数。 A number 0-128 needs only one byte. 0-128号仅需要一个字节。

Microsoft uses these functions to store/retrieve the String length prefix when save to Stream. 保存到Stream时,Microsoft使用这些函数来存储/检索String长度前缀。

To use these Functions, you can create own Class derived from BinaryReader / BinaryWriter. 要使用这些功能,您可以创建自己的从BinaryReader / BinaryWriter派生的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM