可变长度整数编码

我正在尝试对LZ1 / LZ77减压算法进行逆向工程。 要输出的解码缓冲器/窗口的区域的长度在文件中被编码为可变长度整数。 我已尽可能多地阅读有关可变长度整数编码的内容,在这种情况下使用的方法似乎与我见过的其他方法不同。 也许是为了避免专利问题或者只是为了混淆。 包含的代码可能不完整,但此时它至少处理了几个文件。

我无法看到,如果有的话,下面使用的公式可以简化为更简单的方法。 大多数可变长度整数编码算法使用某种循环,但对于这一点,我无法做到这一点,因为在评估每个半字节时,公式似乎并不一致。

建议非常感谢。

private static int getLength(BitReader bitStream) { const int minSize = 2; int length = 0; byte nibble3, nibble2, nibble1; nibble3 = bitStream.ReadNibble(); if (nibble3 >= 0xc) { nibble2 = bitStream.ReadNibble(); nibble1 = bitStream.ReadNibble(); if (nibble3 == 0xF & nibble2 == 0xF & nibble1 == 0xF) return -1; if ((nibble3 & 2) != 0) { length = (((((nibble3 & 7) + 3) << 6) + 8)) + ((nibble2 & 7) << 3) + nibble1 + minSize; } else if ((nibble3 & 1) != 0) { length = (((nibble3 & 7) << 6) + 8) + ((((nibble2 & 7)) + 1) << 3) + nibble1 + minSize; } else { length = ((((nibble3 & 7) << 4) + 8)) + ((nibble2 & 7) << 4) + nibble1 + minSize; } } else if ((nibble3 & 8) != 0) { nibble1 = bitStream.ReadNibble(); length = ((((nibble3 & 7) << 1) + 1) << 3) + nibble1 + minSize; } else { length = nibble3 + minSize; } return length; } 

事实certificate,使用的可变长度整数编码算法与Dlugosz的可变长度整数编码方法非常相似。 实际上,需要多个计算,而不是单个公式。

基于此,我重新编写了如下代码。 我仍在试图弄清楚使用前导0xFFF的机制的确切格式。

  private static int getLength(BitReader bitStream) { const int minSize = 2; int length = 0; byte nibble3, nibble2, nibble1; byte nibble; nibble = bitStream.ReadNibble(); if (nibble == 0xF) { nibble2 = bitStream.ReadNibble(); nibble1 = bitStream.ReadNibble(); if (nibble2 == 0xf && nibble1 == 0xF) { //The next nibble specifies the number of nibbles to be read, maybe. byte nibblesToRead = (byte) (bitStream.ReadNibble()) ; //The Dlugosz' mechanism would use a mask on the value but that doesn't appear to be the case here. //nibblesToRead &= 7; //switch (nibblesToRead & 7){ // case 0: nibblesToRead = 5; break; // case 1: nibblesToRead = 8; break; // case 2: nibblesToRead = 16; break; //} byte value=0; byte[] values = new byte[nibblesToRead]; bool c=true; for (int i = 0; i < nibblesToRead; i++) { value = bitStream.ReadNibble(); //values[i] = value; length += (((value << 1) | 1) << 3); } value = bitStream.ReadNibble(); length += value; } } else if((nibble >= 0xC)){ nibble2 = bitStream.ReadNibble(); nibble1 = bitStream.ReadNibble(); length = ((((((nibble & 1) <<1)|1))<< 3) + ((nibble2<<1)|1)<<3)+nibble1; } else if ((nibble & 8)!=0){ nibble1 = bitStream.ReadNibble(); length = ((((nibble & 3)<<1) | 1) << 3) + nibble1; } else{ length=nibble; } return length + minSize; };