LEB128 Encoder/Decoder

Encode integers to WASM-style Little Endian Base 128 format

Encode and decode integers using LEB128, the variable-length integer format used by WebAssembly and DWARF. Supports both unsigned LEB128 and signed SLEB128, with BigInt precision and hex byte output. Runs in your browser. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What is LEB128?

LEB128 (Little Endian Base 128) is a variable-length encoding for integers. Each byte holds 7 bits of the number plus one continuation flag, so small values take fewer bytes. WebAssembly binaries and the DWARF debug format both use it heavily.

LEB128, short for Little Endian Base 128, is the variable-length integer encoding used inside WebAssembly modules and the DWARF debugging format. This tool converts an integer to its LEB128 byte sequence and back, in both the unsigned and the signed (SLEB128) variants.

How it works

Each output byte carries 7 bits of the number in its low bits and a continuation flag in its high bit (0x80). For unsigned encoding the value is shifted right 7 bits at a time; the continuation bit is set on every byte except the last:

624485 -> E5 8E 26
  byte0 = 0xE5 (continuation set)
  byte1 = 0x8E (continuation set)
  byte2 = 0x26 (last byte)

Signed encoding (SLEB128) uses an arithmetic right shift so the sign propagates, and it stops once the remaining value is 0 (for non-negatives) or -1 (for negatives) and the sign bit of the final 7-bit group already matches. Decoding reverses the process: combine each group with a left shift of 7 times its index, and for signed values sign-extend if the final group’s bit 0x40 is set.

Where LEB128 appears in practice

WebAssembly binary format uses unsigned LEB128 for every integer constant, function index, local index, type index, and section length in the .wasm binary. This is why hand-disassembling a .wasm file requires knowing how to strip continuation bits. DWARF — the debug information format embedded in ELF and Mach-O binaries — uses both unsigned and signed LEB128 heavily in its abbreviation tables, attribute values, and line-number program instructions.

Signed vs unsigned: a concrete difference

The integer -123456 encoded as SLEB128 and as unsigned LEB128 gives different byte sequences, because the sign bit determines when the encoding can stop:

  • Unsigned: cannot represent -123456 (negatives are undefined in unsigned LEB128).
  • Signed (SLEB128): encodes as C0 BB 78 (3 bytes), using arithmetic right shift and sign-bit checking to terminate correctly.

If you paste SLEB128 bytes into the unsigned decoder, you will get a completely wrong (and usually very large) integer, since the sign extension bits are treated as data. Always match the mode to your data source.

Tips and edge cases

  • When decoding, separate bytes with spaces or commas; tokens like E5, 0xE5, or 229 are all accepted. Mixed formats work fine.
  • The last byte you supply must have its continuation bit cleared (high bit = 0). If all your bytes have the high bit set, the decoder reports the input as incomplete — a common mistake when copying a truncated byte sequence.
  • Encoding 0 produces exactly one zero byte. This is the canonical minimal form used in WebAssembly for zero-valued immediates.
  • For signed data, always select SLEB128. Decoding negative numbers with the unsigned decoder will produce an astronomically large positive integer.
  • This tool uses JavaScript BigInt internally, so values beyond 64-bit integers encode and decode correctly without overflow.