#!/bin/sh
set -eu

# Converts a base-16 hash argument to base-62, using only the shell
# and utilities specified by POSIX.1-2024.

hash16="$(printf "%s" "$1" | tr a-f A-F)"
printf "obase=62; ibase=16; %s\n" "$hash16" | bc | {
  # `bc` prints a sequence of ordinal values split across multiple
  # lines using backslash as a continuation character. `read` will,
  # by default, assemble this back into a single line for us.
  read ordinals
  hash62=

  for ord in $ordinals; do
    [ -n "$ord" ] || break
    ord="${ord#0}"  # strip leading 0 so it's not parsed as octal

    offset=61
    [ $ord -lt 36 ] && offset=55
    [ $ord -lt 10 ] && offset=48

    byte=$((ord+offset))
    hash62="$hash62\\$(printf "%03o" $byte)"
  done

  printf "$hash62\n"
}
