По сути, идея 7-битного кодированного Int32
состоит в том, чтобы уменьшить количество байтов, необходимых для небольших значений. Это работает так:
- Берутся первые 7 младших значащих битов исходного значения.
- Если это значение превышает то, что может поместиться в эти 7 битов, 8-й бит устанавливается в 1, указывая, что должен быть прочитан другой байт. В противном случае этот бит равен 0, и чтение заканчивается здесь.
- Следующий байт считывается, его значение сдвигается влево на 7 битов и устанавливается на ранее прочитанное значение, чтобы объединить их вместе. Опять же, 8-й бит этого байта указывает, должен ли считываться другой байт (сдвигая значение чтения еще 7 раз).
- Это продолжается до тех пор, пока не будет прочитано максимум 5 байтов (потому что даже
Int32.MaxValue
не потребует более 5 байтов, когда из каждого байта украден только 1 бит). Если старший бит 5-го байта все еще установлен, вы прочитали что-то, что не является 7-битным кодированным Int32.
Обратите внимание, что поскольку он записывается побайтово, для этих значений порядковый номер не имеет значения вообще. Следующее количество байтов требуется для данного диапазона значений:
- 1 байт: от 0 до 127
- 2 байта: от 128 до 16 383
- 3 байта: от 16 384 до 2 097 151
- 4 байта: от 2 097 152 до 268 435 455
- 5 байтов: от 268 435 456 до 2 147 483 647 (
Int32.MaxValue
) и от 2 147 483 648 (Int32.MinValue
) до -1
Как видите, реализация довольно тупая и всегда требует 5 байтов для отрицательных значений, поскольку знаковый бит - это 32-й бит исходного значения, всегда заканчивающийся 5-м байтом.
Таким образом, я не рекомендую его для отрицательных значений или значений больше ~ 250 000 000. Я видел только то, что он использовался внутренне для префикса длины строки строк .NET (тех, которые вы можете читать / писать с помощью BinaryReader.ReadString
и BinaryReader.WriteString
), описывая количество символов, за которыми следует строка, только с положительными значениями .
Хотя вы можете искать оригинальный источник .NET , я использую разные реализации в моей библиотеке BinaryData .