friendly32

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2026 License: LGPL-2.1, LGPL-2.1-or-later Imports: 3 Imported by: 0

README

go-friendly32

Go Reference

Package go.heptapod.dev/friendly32 is a Go module that provides encoding and decoding of binary data in a human-friendly base32 alphabet.

It uses the Go standard library's encoding/base32 with custom alphabet 0123456789abcdefghjkmnpqrtuvwxyz and optional padding character -.

Notable properties of the chosen alphabet:

  • Sorting a list of encoded values by locale-naïve (LC_COLLATE=C) lexical ASCII sort gives the same order you'd get from decoding those values and applying a lexical sort to their byte strings.

  • If padding characters are used, the padding is URL-safe and does not disrupt the overall sort order. Padded and unpadded encodings of the same value will always be contiguous in the sorted list, with no other values landing between them.

  • Encoded values can still be decoded correctly even after case-mangling: values can survive Caps Lock, autocapitalization of initial letters via on-screen keyboards, or auto-uppercasing applied by business software.

  • Encoded values can still be decoded correctly even when digits are misinterpreted as letters due to ambiguous fonts.

Criteria and rationale

To obtain the benefits listed above, we must select an alphabet that obeys both of the following criteria:

  1. The symbols should be URL-safe ASCII, ordered by ascending value.

  2. No two symbols should equal one another under case folding.

We choose the digits and lowercase letters as our pool of candidates, giving us 10 + 26 = 36 potential symbols, of which we must choose 4 to discard.

The experience of the author suggests that the four most easily confused letter/digit pairs are: uppercase O vs digit 0, uppercase I vs digit 1, lowercase L vs digit 1, and uppercase S vs digit 5. We discard both the upper and lower cases of each letter in this list, fixing a 5th ambiguity between uppercase I vs lowercase L for free in the process.

Finally, we select - over the traditional =, firstly because - is URL-safe where = is not, and secondly because - sorts less than digit 0 in the locale-naïve ASCII sort order.

Documentation

Overview

Package friendly32 encodes/decodes binary data in a human-friendly base32 alphabet.

This package uses the Go standard library's encoding/base32 with custom alphabet "0123456789abcdefghjkmnpqrtuvwxyz" and optional padding character "-".

See README.md for more information.

Index

Constants

View Source
const Alphabet = "0123456789abcdefghjkmnpqrtuvwxyz"

Alphabet is friendly32's custom alphabet. It omits "i", "l", "o", and "s".

Variables

View Source
var Encoding = base32.NewEncoding(Alphabet).WithPadding(base32.NoPadding)

Encoding is a base32.Encoding object that uses Alphabet as its alphabet and no padding.

View Source
var PaddedEncoding = base32.NewEncoding(Alphabet).WithPadding('-')

PaddedEncoding is a base32.Encoding object that uses Alphabet as its alphabet and '-' as the padding character.

The padding character '-' is chosen over the more traditional '=' because (1) it is URL-safe and, (2) it is less disruptive to lexical sort order, since its ASCII value is less than that of any symbol in Alphabet.

Functions

func AppendDecode

func AppendDecode(output []byte, input []byte) ([]byte, error)

AppendDecode is a wrapper around base32.Encoding.AppendDecode on Encoding that automatically calls FixBytes on the input text.

func AppendEncode

func AppendEncode(output []byte, input []byte) []byte

AppendEncode is a trivial wrapper around base32.Encoding.AppendEncode on Encoding.

func Decode

func Decode(output []byte, input []byte) (int, error)

Decode is a wrapper around base32.Encoding.Decode on Encoding that automatically calls FixBytes on the input text.

func DecodeString

func DecodeString(input string) ([]byte, error)

DecodeString is a wrapper around base32.Encoding.DecodeString on Encoding that automatically calls FixString on the input text.

func DecodedLen

func DecodedLen(n int) int

DecodedLen is a trivial wrapper around base32.Encoding.DecodedLen on Encoding.

func Encode

func Encode(output []byte, input []byte)

Encode is a trivial wrapper around base32.Encoding.Encode on Encoding.

func EncodeToString

func EncodeToString(input []byte) string

EncodeToString is a trivial wrapper around base32.Encoding.EncodeToString on Encoding.

func EncodedLen

func EncodedLen(n int) int

EncodedLen is a trivial wrapper around base32.Encoding.EncodedLen on Encoding.

func FixByte

func FixByte(ch byte) (byte, bool)

FixByte attempts to auto-correct a single ASCII character, which represents a potential friendly32 symbol.

If the byte has been corrected, returns (corrected, true); otherwise, returns (original, false).

func FixBytes

func FixBytes(input []byte) []byte

FixBytes attempts to auto-correct a slice of ASCII bytes, which contains potential friendly32 symbols.

The original byte slice is never modified. If any corrections are necessary, the slice is cloned before the corrections are made.

func FixBytesInPlace

func FixBytesInPlace(input []byte)

FixBytesInPlace attempts to auto-correct a slice of ASCII bytes, which contains potential friendly32 symbols. The original byte slice is modified.

func FixRune

func FixRune(ch rune) (rune, bool)

FixRune attempts to auto-correct a single Unicode code point, which represents a potential friendly32 symbol.

If the rune has been corrected, returns (corrected, true); otherwise, returns (original, false).

func FixString

func FixString(input string) string

FixString attempts to auto-correct a Unicode string, which contains potential friendly32 symbols.

func NewDecoder

func NewDecoder(r io.Reader) io.Reader

NewDecoder is a wrapper around base32.NewDecoder on Encoding that automatically calls FixBytesInPlace on the input text.

func NewEncoder

func NewEncoder(w io.Writer) io.WriteCloser

NewEncoder is a trivial wrapper around base32.NewEncoder on Encoding.

func NewPaddedDecoder

func NewPaddedDecoder(r io.Reader) io.Reader

NewPaddedDecoder is a wrapper around base32.NewDecoder on PaddedEncoding that automatically calls FixBytesInPlace on the input text.

func NewPaddedEncoder

func NewPaddedEncoder(w io.Writer) io.WriteCloser

NewPaddedEncoder is a trivial wrapper around base32.NewEncoder on PaddedEncoding.

func PaddedAppendDecode

func PaddedAppendDecode(output []byte, input []byte) ([]byte, error)

PaddedAppendDecode is a wrapper around base32.Encoding.AppendDecode on PaddedEncoding that automatically calls FixBytes on the input text.

func PaddedAppendEncode

func PaddedAppendEncode(output []byte, input []byte) []byte

PaddedAppendEncode is a trivial wrapper around base32.Encoding.AppendEncode on PaddedEncoding.

func PaddedDecode

func PaddedDecode(output []byte, input []byte) (int, error)

PaddedDecode is a wrapper around base32.Encoding.Decode on PaddedEncoding that automatically calls FixBytes on the input text.

func PaddedDecodeString

func PaddedDecodeString(input string) ([]byte, error)

PaddedDecodeString is a wrapper around base32.Encoding.DecodeString on PaddedEncoding that automatically calls FixString on the input text.

func PaddedDecodedLen

func PaddedDecodedLen(n int) int

PaddedDecodedLen is a trivial wrapper around base32.Encoding.DecodedLen on PaddedEncoding.

func PaddedEncode

func PaddedEncode(output []byte, input []byte)

PaddedEncode is a trivial wrapper around base32.Encoding.Encode on PaddedEncoding.

func PaddedEncodeToString

func PaddedEncodeToString(input []byte) string

PaddedEncodeToString is a trivial wrapper around base32.Encoding.EncodeToString on PaddedEncoding.

func PaddedEncodedLen

func PaddedEncodedLen(n int) int

PaddedEncodedLen is a trivial wrapper around base32.Encoding.EncodedLen on PaddedEncoding.

Types

This section is empty.

Jump to

Keyboard shortcuts

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