vint

package module
v0.0.0-...-ade77a9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 10, 2024 License: Apache-2.0 Imports: 4 Imported by: 1

README

vint

Short for Variable INTeger, vint is a library for encoding / decoding unsigned integers to / from a slice of bytes.

Format

The encoding is simple:

  • If n < MaxUint8, encode the number with its usual 8-bit representation (with the most-significant-bit on the left).
  • If n >= MaxUint8, set the first 8 bits to all 1s, subtract MaxUint8 from n, and attempt to encode the remainder in the next 16 bits.
  • If the remainder >= MaxUint16, set those 16 bits to all 1s, subtract MaxUint16 and attempt to encode the remainder in the next 32 bits.
  • If the remainder >= MaxUint32, set those 32 bits to all 1s, subtract MaxUint32 and encode the remainder in the next 64 bits.

All fields are encoded with the most-significant-bit on the left, ie big-endian.

Examples:

n B0 B1 B2 B3 B4 B5 B6
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
254 254
255 255 0 0
256 255 0 1
257 255 0 2
1500 255 4 221
9000 255 34 41
65534 255 254 255
65535 255 255 0
65536 255 255 1
65537 255 255 2
65789 255 255 254
65790 255 255 255 0 0 0 0
65791 255 255 255 0 0 0 1
65792 255 255 255 0 0 0 2

Usage

From examples/42.go:

import (
	"fmt"
	"github.com/SamuraiAck/vint"
)

func main() {
	fmt.Printf("Encode(42) produces %v\n", vint.Encode(uint8(42)))
	n, err := vint.Decode([]byte{42})
	fmt.Printf("Decode([]byte{42}) produces %v, %v\n", n, err)
	fmt.Printf("Length(42) produces %v\n", vint.Length(uint8(42)))
}
eric@ava:~/vint$ go run examples/42.go
Encode(42) produces [42]
Decode([]byte{42}) produces 42, <nil>
Length(42) produces 1
eric@ava:~/vint$ 

Pros

  • Prefix-free, self-delimited, every integer has a unique encoding.
  • No overhead for integers below 255.
  • The encoding is simple enough that a human can inspect and decode it manually, making it suitable for eg low-bandwidth network maintenance protocols that consist primarily of short type-length-value tuples (TLVs).
  • As there are very few operations involved, optimized implementations should be faster than more complicated encodings in benchmarks.

Cons

  • No error detection.
  • This encoding is not space-efficient for integers greater than 254, so any speed advantage due to its simplicity will probably be lost to transmission delays.
  • This encoding is inefficient for negative integers cast to unsigned ints. Other varint libraries such as encoding/binary are better for signed integers.
  • This library does not currently handle integers greater than MaxUint64. Decode will return an overflow error if the bytes passed to it correspond to an integer > MaxUint64.

Future work

  • Optimize Encode / Decode functions.
  • Add support for big.Ints?
  • Update if Golang ever adds uint128.
  • Make a bit-oriented library that puts the least-significant-bit on the left.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrTooSmall = errors.New("Decode: buffer contains insufficient data")
	ErrTooLarge = errors.New("Decode: encoded number is greater than MaxUint64")
)

Functions

func Decode

func Decode(b []byte) (uint64, error)

Decode decodes the unsigned integer stored in b. Return values are the integer as a uint64 and nil if successful, or zero and the error if not.

func Encode

func Encode[T constraints.Unsigned](i T) []byte

Encode encodes any unsigned integer passed to it and returns its vint representation in a slice of bytes.

func Length

func Length[T constraints.Unsigned](n T) int

Length(n) returns the number of bytes needed to encode n.

Types

This section is empty.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL