Productivity and Utilities

Varint and Zigzag Encoder

Enter whole numbers to encode, or switch to Decode and paste hex bytes, and pick the format.

Your numbers

Direction

Unsigned varint (protobuf uint64) and unsigned LEB128 are the same bytes. Zigzag is protobuf sint32 and sint64. Signed LEB128 is used in DWARF and WebAssembly.

To encode: whole numbers separated by lines, spaces or commas, in decimal or 0x hex. To decode: hex bytes such as AC 02.

Result

Bytes

01 7F 80 01 AC 02 80 80 01

5 numbers in 9 bytes.

Total bytes
9
Numbers
5
Longest value
3 bytes

Each number

NumberBytesLength
1011
1277F1
12880 012
300AC 022
1638480 80 013
How this was calculated
  1. The number is cut into groups of 7 bits, starting with the least significant group.
  2. Each group is written as one byte. Every byte except the last has its top bit set to 1, which means more bytes follow.
  3. Unsigned values stop when no bits remain.

Calculated using SumPanda.com · https://sumpanda.com/varint-and-zigzag-encoder/

Results are estimates for general information. Verify important figures before relying on them.

Next step

How to use the varint and zigzag encoder

  1. Choose Numbers to bytes or Bytes to numbers.
  2. Pick the format: unsigned varint, zigzag varint or signed LEB128.
  3. To encode, enter whole numbers, one per line or separated by spaces or commas. Hex numbers such as 0xFF are accepted.
  4. To decode, paste hex bytes such as AC 02. Read the numbers and bytes in the table.

Formula

split the number into groups of 7 bits, least significant group first

write each group as a byte, with the top bit set on every byte except the last

zigzag: n >= 0 gives 2n, n < 0 gives -2n - 1

signed LEB128: stop when the remaining bits all equal the sign bit of the last group

Unsigned varints from Protocol Buffers and unsigned LEB128 use the same bytes. The range is 0 to 18,446,744,073,709,551,615 for unsigned and -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 for signed values.

Small numbers use one or two bytes

The numbers 1, 127, 128, 300 and 16,384 encode as 01, 7F, 80 01, AC 02 and 80 80 01. Nine bytes carry five numbers. The number 300 is 100101100 in binary. Its low seven bits, 0101100, become AC after the continuation bit is added, and the remaining bits, 10, become 02.

In zigzag form, 0, -1, 1 and -2 become 0, 1, 2 and 3, so they take one byte each. The largest 32 bit values are longer: 2,147,483,647 maps to 4,294,967,294 and is written FE FF FF FF 0F, five bytes. Signed LEB128 writes -2 as 7E, 127 as FF 00 and -128 as 80 7F.

Why zigzag exists

A plain varint writes a negative number as a huge unsigned one, so in Protocol Buffers a negative int64 takes 10 bytes. Zigzag encoding interleaves positive and negative numbers so that small values of either sign give small codes. It is used for the sint32 and sint64 field types.

Signed LEB128 handles negative numbers a different way, by sign extension, and is used in formats such as DWARF and WebAssembly. The two are not interchangeable, so choose the one your format specifies.

Checking real data

Decode mode reads a stream of bytes as a series of varints, so you can paste a few bytes from a dump and see the numbers. Open a file as hex with the Hex Viewer to find them. For fixed width integers, see the Byte Order Swap Calculator, and for shifts and masks, try the Bitwise Calculator.

Assumptions and limits

  • Values are whole numbers of at most 64 bits.
  • A varint is at most 10 bytes long.
  • Bytes are entered in hex, with or without spaces.
  • At most 200 numbers are encoded at a time.
  • The numbers shown when the page opens are examples.

Formulas reviewed October 10, 2026. See the calculation methodology for how SumPanda rounds, tests and sources its formulas.

Frequently asked questions

Is a varint the same as LEB128?

For unsigned numbers, yes. Protocol Buffers varints and unsigned LEB128 write the same bytes. Signed numbers differ between zigzag and signed LEB128.

Why does 128 need two bytes?

One byte carries only 7 bits of the number, so it holds 0 to 127. At 128 the number needs an eighth bit, so a second byte is added.

What happens with a cut-off byte stream?

If the last byte still has its top bit set, the number is incomplete. The page says the last value is cut off instead of guessing.

Can I decode bytes with a different format than I encoded?

You can, but the numbers will be different. The same bytes mean different values as unsigned, zigzag and signed LEB128, so use the format of your source.