Luigit
repositories / bugabinga.net

bugabinga.net

personal infrastructure for bugabinga!

owned by admin

services/luci/internal/proquint/proquint.go

Raw
// Package proquint renders identifiers as pronounceable quintuplets per
// arXiv:0901.4016: alternating consonants and vowels, five letters per
// sixteen bits, blocks joined by dashes.
package proquint

import (
	"encoding/binary"
	"strings"
)

const consonants = "bdfghjklmnprstvz"
const vowels = "aiou"

// Encode renders a 64-bit identifier as four proquint blocks.
func Encode(id int64) string {
	var bytes [8]byte
	binary.BigEndian.PutUint64(bytes[:], uint64(id))
	blocks := make([]string, 4)
	for i := range blocks {
		blocks[i] = block(binary.BigEndian.Uint16(bytes[i*2:]))
	}
	return strings.Join(blocks, "-")
}

func block(word uint16) string {
	return string([]byte{
		consonants[word>>12],
		vowels[(word>>10)&3],
		consonants[(word>>6)&15],
		vowels[(word>>4)&3],
		consonants[word&15],
	})
}

// Decode parses four proquint blocks into a 64-bit identifier.
func Decode(text string) (int64, bool) {
	bytes, ok := PrefixBytes(text)
	if !ok || len(bytes) != 8 {
		return 0, false
	}
	return int64(binary.BigEndian.Uint64(bytes)), true
}

// PrefixBytes parses one to four proquint blocks into the leading bytes of
// a 64-bit identifier, enabling unique-prefix resolution like git.
func PrefixBytes(text string) ([]byte, bool) {
	if text == "" {
		return nil, false
	}
	parts := strings.Split(text, "-")
	if len(parts) > 4 {
		return nil, false
	}
	out := make([]byte, 0, len(parts)*2)
	for _, part := range parts {
		if len(part) != 5 {
			return nil, false
		}
		letters := []byte(part)
		consonant := func(index int) (uint16, bool) {
			value := strings.IndexByte(consonants, letters[index])
			return uint16(value), value >= 0
		}
		c1, ok := consonant(0)
		if !ok {
			return nil, false
		}
		v1 := strings.IndexByte(vowels, letters[1])
		c2, ok := consonant(2)
		if !ok || v1 < 0 {
			return nil, false
		}
		v2 := strings.IndexByte(vowels, letters[3])
		c3, ok := consonant(4)
		if !ok || v2 < 0 {
			return nil, false
		}
		word := c1<<12 | uint16(v1)<<10 | c2<<6 | uint16(v2)<<4 | c3
		out = binary.BigEndian.AppendUint16(out, word)
	}
	return out, true
}