aboutsummaryrefslogtreecommitdiffhomepage
path: root/shortid.go
diff options
context:
space:
mode:
Diffstat (limited to 'shortid.go')
-rw-r--r--shortid.go38
1 files changed, 38 insertions, 0 deletions
diff --git a/shortid.go b/shortid.go
new file mode 100644
index 0000000..9cfd076
--- /dev/null
+++ b/shortid.go
@@ -0,0 +1,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
+}