aboutsummaryrefslogtreecommitdiffhomepage
path: root/shortid.go
blob: 9cfd0760d1db3922203fc9c865734f6d143abfcd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package main

import (
	"encoding/base32"
	"encoding/binary"
	"fmt"
	"strings"
)

var b32 = base32.StdEncoding.WithPadding(base32.NoPadding)

func encodeID(id int64) (string, error) {
	if id < 0 {
		return "", fmt.Errorf("id out of range: %d", id)
	}
	buf := make([]byte, 8)
	binary.BigEndian.PutUint64(buf, uint64(id))
	// Trim leading zero bytes, keep at least 2 bytes (4 chars).
	i := 0
	for i < 6 && buf[i] == 0 {
		i++
	}
	return b32.EncodeToString(buf[i:]), nil
}

func decodeID(s string) (int64, error) {
	s = strings.ToUpper(s)
	buf, err := b32.DecodeString(s)
	if err != nil {
		return 0, fmt.Errorf("invalid short id: %w", err)
	}
	if len(buf) == 0 || len(buf) > 8 {
		return 0, fmt.Errorf("invalid short id")
	}
	padded := make([]byte, 8)
	copy(padded[8-len(buf):], buf)
	return int64(binary.BigEndian.Uint64(padded)), nil
}