#!/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" }