package module
v1.0.0 Latest Latest

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

Go to latest
Published: Oct 2, 2021 License: MIT Imports: 4 Imported by: 1


Basexx - Convert between digit strings and various number bases

Go Reference Go Report Card Tests Coverage Status

This is basexx, a package for converting numbers to digit strings in various bases and vice versa.


To get the Base30 encoding of the number 412:

result, err := basexx.Digits(412, basexx.Base30)

To decode the base30 digit string "fr":

result, err := basexx.Value("fr", basexx.Base30)

To convert a digit string x in base from to a new digit string in base to:

var (
  src     = basexx.NewBuffer(x, from)
  destbuf = make([]byte, basexx.Length(from, to, len(x)))
  dest    = basexx.NewBuffer(destbuf, to)
_, err := Convert(dest, src)
if err != nil { ... }
result := dest.Written()

To define your own new number base:

// ReverseBase10 uses digits '9' through '0' just to mess with you.
type ReverseBase10 struct{}

func (ReverseBase10) N() int64 { return 10 }

func (ReverseBase10) Encode(val int64) (byte, error) {
  if val < 0 || val > 9 {
    return 0, errors.New("digit value out of range")
  return byte('9' - val), nil

func (ReverseBase10) Decode(digit byte) (int64, error) {
  if digit < '0’ || digit > '9' {
    return 0, errors.New("invalid encoded digit")
  return int64(9 - (digit - '0’))



Package basexx permits converting between digit strings of arbitrary bases.




View Source
const (
	// Base2 uses digits "0" and "1"
	Base2 = Alnum(2)

	// Base8 uses digits "0" through "7"
	Base8 = Alnum(8)

	// Base10 uses digits "0" through "9"
	Base10 = Alnum(10)

	// Base12 uses digits "0" through "9" plus "a" and "b"
	Base12 = Alnum(12)

	// Base16 uses digits "0" through "9" plus "a" through "f"
	Base16 = Alnum(16)

	// Base32 uses digits "0" through "9" plus "a" through "v"
	Base32 = Alnum(32)

	// Base36 uses digits "0" through "9" plus "a" through "z"
	Base36 = Alnum(36)


View Source
var Base30 base30

Base30 uses digits 0-9, then lower-case bcdfghjkmnpqrstvwxyz. It excludes vowels (to avoid inadvertently spelling naughty words) and the letter "l". Note, this is not the same as basexx.Alnum(30), which uses 0-9 and then abcdefghijklmnopqrst.

View Source
var Base50 base50

Base50 uses digits 0-9, then lower-case bcdfghjkmnpqrstvwxyz, then upper-case BCDFGHJKMNPQRSTVWXYZ. It excludes vowels (to avoid inadvertently spelling naughty words) plus lower- and upper-case L.

View Source
var Base62 base62

Base62 uses digits 0..9, then a..z, then A..Z.

View Source
var Base94 base94

Base94 uses all printable ASCII characters (33 through 126) as digits.

View Source
var Binary binary

Binary is base 256 encoded the obvious way: digit value X = byte(X).

View Source
var ErrInvalid = errors.New("invalid")

ErrInvalid is used for invalid input to Base.Encode and Base.Decode.


func Convert

func Convert(dest Dest, src Source) (int, error)

Convert converts the digits of src, writing them to dest. Both src and dest specify their bases. Return value is the number of digits written to dest (even in case of error). This function consumes all of src before producing any of dest, so it may not be suitable for input streams of arbitrary length.

package main

import (


func main() {
	const base10val = "12345"

	// The basexx package has no predefined Base20 type,
	// but any base 2 through 36 using alphanumeric digits
	// can be defined with basexx.Alnum.
	base20 := basexx.Alnum(20)

	// A Buffer can serve as a Source for Convert.
	src := basexx.NewBuffer([]byte(base10val), basexx.Base10)

	// Allocate enough space (according to basexx.Length) for holding the result.
	destBuf := make([]byte, basexx.Length(10, 20, len(base10val)))

	// A Buffer can also serve as a Dest for Convert.
	dest := basexx.NewBuffer(destBuf[:], base20)

	_, err := basexx.Convert(dest, src)
	if err != nil {

	// Use Written to get the written-to portion of the allocated byte slice (destBuf).
	result := dest.Written()

	fmt.Printf("%s (base 10) = %s (base 20)", base10val, string(result))


12345 (base 10) = 1ah5 (base 20)

func Digits

func Digits(val int64, base Base) (string, error)

Digits converts a (non-negative) integer into a digit string in the given base.

func Length

func Length(from, to int64, n int) int

Length computes the maximum number of digits needed to convert `n` digits in base `from` to base `to`.

func Value

func Value(inp string, base Base) (int64, error)

Value converts a digit string in the given base into its integer value.


type Alnum

type Alnum int

Alnum is a type for bases from 2 through 36, where the digits for the first 10 digit values are '0' through '9' and the remaining digits are 'a' through 'z'. For decoding, upper-case 'A' through 'Z' are the same as lower-case.

func (Alnum) Decode

func (a Alnum) Decode(digit byte) (int64, error)

Decode implements Base.Decode.

func (Alnum) Encode

func (a Alnum) Encode(val int64) (byte, error)

Encode implements Base.Encode.

func (Alnum) N

func (a Alnum) N() int64

N implements Base.N.

type Base

type Base interface {
	// N is the number of the base,
	// i.e. the number of unique digits.
	// Behavior is undefined if the value of N() varies during the lifetime of a Base
	// or if N() < 2.
	N() int64

	// Encode converts a digit value to the byte representing its digit.
	// The input must be a valid digit value between 0 and N()-1, inclusive.
	Encode(int64) (byte, error)

	// Decode converts an encoded digit byte into its numeric value.
	Decode(byte) (int64, error)

Base is the type of a base.

type Buffer

type Buffer struct {
	// contains filtered or unexported fields

Buffer can act as a Source or a Dest (but not both at the same time) in the case where each byte in a given slice encodes a single digit in the desired base. The digits in the buffer are in the expected order: namely, most-significant first, least-significant last.

func NewBuffer

func NewBuffer(buf []byte, base Base) *Buffer

NewBuffer produces a Buffer from the given byte slice described by the given Base.

func (*Buffer) Base

func (s *Buffer) Base() int64

Base tells the buffer's Base.

func (*Buffer) Prepend

func (s *Buffer) Prepend(val int64) error

Prepend prepends the digit with the given value, encoded according to the buffer's Base.

func (*Buffer) Read

func (s *Buffer) Read() (int64, error)

Read implements io.Reader.

func (*Buffer) Written

func (s *Buffer) Written() []byte

Written returns the slice of encoded digits contained in the buffer.

type Dest

type Dest interface {
	// Prepend encodes the next-most-significant digit value and prepends it to the destination.
	Prepend(int64) error

	// Base gives the base of the Dest.
	// Digit values in the Dest must all be between 0 and Base()-1, inclusive.
	// Behavior is undefined if the value of Base() varies during the lifetime of a Dest
	// or if Base() < 2.
	Base() int64

Dest is a destination for writing digits in a given base. Digits are written right-to-left, from least significant to most.

type Source

type Source interface {
	// Read produces the value of the next-least-significant digit in the source.
	// The value must be between 0 and Base()-1, inclusive.
	// End of input is signaled with the error io.EOF.
	Read() (int64, error)

	// Base gives the base of the Source.
	// Digit values in the Source must all be between 0 and Base()-1, inclusive.
	// Behavior is undefined if the value of Base() varies during the lifetime of a Source
	// or if Base() < 2.
	Base() int64

Source is a source of digit values in a given base.


Path Synopsis

Jump to

Keyboard shortcuts

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