VAR Protobuf Integer Utility

Protobuf Varint & ZigZag Calculator

Use this Protobuf Varint & ZigZag Calculator to encode unsigned integers into Protocol Buffers varint bytes, decode protobuf varint hex back to decimal, and convert signed sint32 or sint64 values using ZigZag encoding.

✓ Varint Encoder ✓ Varint Decoder ✓ ZigZag Encode ✓ ZigZag Decode ✓ 64-Bit BigInt
128
Calculate Protobuf Varint & ZigZag
● Ready
ZigZag efficiently maps signed integers to unsigned varint values.
Used for range validation. Calculations use JavaScript BigInt.
Unsigned mode accepts non-negative decimal integers. ZigZag mode accepts signed decimal integers.
Enter one varint only. Spaces, commas, colons, hyphens and 0x prefixes are accepted.
Important: ordinary protobuf varints and ZigZag are different operations. Fields declared as uint32 or uint64 use the unsigned value directly. Fields declared as sint32 or sint64 first apply ZigZag encoding and then encode the resulting unsigned integer as a varint.
Protobuf Integer Result Encoded
Protobuf Varint Bytes
Signed Input
Unsigned Value
ZigZag Value
Varint Bytes
Byte Count
Encoded Bits
Binary Value
Hex Integer
Integer Width
Encoding Type
Canonical Varint
Range Status
Byte Hex Binary Continuation 7 Data Bits Bit Shift
Varint / ZigZag Calculation Breakdown -
Varint Hex Bytes
-

What Is a Protobuf Varint?

A protobuf varint is a variable-length integer representation used by Protocol Buffers for several integer-like field types. Instead of always storing an integer in four or eight bytes, a varint stores seven value bits in each byte and uses the high bit as a continuation flag.

Small non-negative values therefore require very little space. Values from 0 through 127 fit in one byte, while progressively larger values require additional bytes.

How Protobuf Varint Encoding Works

Each varint byte contains:

bit 7: continuation flag bits 6..0: seven value bits

If another varint byte follows, the most significant bit is set to one. The final byte has a zero continuation bit.

Protobuf Varint Example: 150

The decimal value 150 is represented in binary as:

150 decimal = 10010110₂

Split the value into groups of seven bits beginning with the least significant bits:

150 → 0000001 0010110

The low seven bits are transmitted first. Because another group follows, the continuation bit is set:

0010110 + continuation 1 = 10010110 = 0x96 0000001 + continuation 0 = 00000001 = 0x01 Result: 96 01

Varint Byte Ranges

Varint Bytes Unsigned Range
1 byte0 – 127
2 bytes128 – 16,383
3 bytes16,384 – 2,097,151
4 bytes2,097,152 – 268,435,455
5 bytes268,435,456 – 34,359,738,367
Up to 10Required for the full uint64 range

What Is ZigZag Encoding?

ZigZag encoding maps signed integers onto unsigned integers so values near zero remain small before varint encoding.

Signed ZigZag 0 → 0 -1 → 1 1 → 2 -2 → 3 2 → 4 -3 → 5

The mapping interleaves negative and positive values instead of allowing small negative values to turn into very large unsigned representations.

ZigZag Encoding Formula

Conceptually, ZigZag can be expressed without relying on a specific programming language’s signed shift behavior:

if n ≥ 0: ZigZag(n) = 2 × n if n < 0: ZigZag(n) = -2 × n - 1

For example:

n = -75 ZigZag = -2 × (-75) - 1 = 150 - 1 = 149

ZigZag Decode Formula

To convert the unsigned ZigZag value back to the original signed integer:

signed = (unsigned >> 1) XOR -(unsigned & 1)

An equivalent conceptual rule is:

even ZigZag value: n = value / 2 odd ZigZag value: n = -(value + 1) / 2

Example: Encode −75 as Protobuf sint64

First ZigZag encode the signed value:

-75 → ZigZag 149

Then encode unsigned 149 as a protobuf varint:

149 → 95 01

Therefore:

sint64 -75 ZigZag: 149 Varint: 95 01

Protobuf uint vs sint

uint32 / uint64

The non-negative integer value is encoded directly as a protobuf varint.

sint32 / sint64

The signed value is ZigZag encoded first, then the resulting unsigned number is encoded as a varint.

Why ZigZag Helps Negative Values

Standard two’s-complement signed integer encodings do not naturally make small negative numbers small when interpreted as unsigned values. ZigZag rearranges the mapping so values close to zero remain close to zero regardless of sign.

That makes sint32 and sint64 efficient when both small negative and small positive values occur frequently.

Protobuf int32 vs sint32

These protobuf field types are not interchangeable at the wire-value level. An int32 uses the normal signed integer varint behavior, while sint32 applies ZigZag encoding first.

If your schema says sint32 or sint64, use ZigZag mode. Do not apply ZigZag merely because a value happens to be negative.

Canonical Protobuf Varints

A value has a shortest possible varint representation. For example, zero should normally be represented as:

00

not a longer continuation sequence that eventually resolves to the same numeric value.

The calculator re-encodes decoded values and reports whether the supplied byte sequence matches the shortest canonical varint representation.

64-Bit Protobuf Integer Precision

JavaScript’s ordinary Number type cannot exactly represent every 64-bit integer. This calculator therefore performs integer arithmetic with BigInt.

That allows exact conversion of values throughout the uint64, sint64, uint32 and sint32 ranges supported by this tool.

Protobuf Integer Ranges

Type Minimum Maximum
uint32 0 4,294,967,295
uint64 0 18,446,744,073,709,551,615
sint32 −2,147,483,648 2,147,483,647
sint64 −9,223,372,036,854,775,808 9,223,372,036,854,775,807

How to Decode Protobuf Varint Hex

To decode a varint, remove the continuation bit from each byte and place each seven-bit group at increasing powers of 128.

96 01 0x96 & 0x7F = 0x16 = 22 0x01 & 0x7F = 1 Value = 22 + (1 << 7) = 22 + 128 = 150

Varint Continuation Bit

The highest bit of every varint byte indicates whether another byte follows.

MSB = 1 → another varint byte follows MSB = 0 → this is the final byte

A stream ending with a byte whose continuation bit remains set is truncated and cannot be decoded as a complete varint.

Common Uses for This Calculator

Protocol Debugging

Check integer bytes copied from protobuf network traffic or diagnostic logs.

Serializer Verification

Compare expected decimal values with generated protobuf byte output.

Embedded Development

Verify lightweight protobuf implementations on microcontrollers.

Reverse Engineering

Inspect wire-level integer values when investigating protobuf data you are authorized to analyze.

Common Protobuf Varint Mistakes

Reading Bytes as Big-Endian

Varint seven-bit groups are arranged least-significant group first.

Forgetting the Continuation Bit

The high bit is control information and is not part of the seven payload bits.

Applying ZigZag to uint Fields

Unsigned protobuf fields use their value directly.

Skipping ZigZag for sint Fields

sint32 and sint64 require ZigZag before varint encoding.

Using JavaScript Number for uint64

Values above the exact integer range of Number can silently lose precision.

Accepting a Truncated Varint

A final byte with its continuation bit still set means more bytes are required.

Protobuf Varint & ZigZag Calculator FAQs

What is a protobuf varint?
A varint is a variable-length unsigned integer representation that stores seven value bits per byte and uses the most significant bit as a continuation flag.
How is 150 encoded as a protobuf varint?
Decimal 150 is encoded as hexadecimal bytes 96 01.
What does protobuf varint 96 01 decode to?
It decodes to unsigned decimal value 150.
How is 300 encoded as a protobuf varint?
Decimal 300 is encoded as AC 02.
What is ZigZag encoding?
ZigZag maps signed integers onto unsigned integers so small negative and positive values both remain efficient when subsequently encoded as varints.
What does ZigZag encode −1 to?
Signed −1 maps to unsigned ZigZag value 1.
What does ZigZag encode 1 to?
Signed positive 1 maps to unsigned ZigZag value 2.
What does ZigZag value 1 decode to?
It decodes to signed −1.
What is the ZigZag value for −75?
Signed −75 maps to unsigned ZigZag value 149.
How is protobuf sint −75 encoded?
ZigZag converts −75 to 149 and protobuf varint encoding converts 149 to bytes 95 01.
Does uint32 use ZigZag?
No. uint32 is encoded directly as an unsigned varint.
Does sint32 use ZigZag?
Yes. sint32 applies ZigZag encoding before protobuf varint encoding.
Does sint64 use ZigZag?
Yes. sint64 uses the same signed-to-unsigned ZigZag concept over the 64-bit range.
How many bytes can a uint64 protobuf varint require?
A full 64-bit unsigned protobuf varint can require up to ten bytes.
What is a protobuf continuation bit?
It is the most significant bit of each varint byte. One means another byte follows, while zero marks the final byte.
What is a canonical varint?
It is the shortest normal byte representation of the decoded unsigned value.
Why does this calculator use BigInt?
BigInt keeps 64-bit integer calculations exact instead of losing precision in JavaScript’s floating-point Number representation.
Is ZigZag the same as two’s complement?
No. Two’s complement is a signed binary representation, while ZigZag is a mapping that rearranges signed integers into unsigned values before varint encoding.

Encode and Decode Protobuf Varints and ZigZag Integers

Enter a decimal integer or protobuf hexadecimal varint to inspect exact unsigned values, ZigZag mappings, byte groups, continuation bits and encoded length for 32-bit or 64-bit Protocol Buffers integer fields.

Scroll to Top