113 lines
2.3 KiB
Bash
113 lines
2.3 KiB
Bash
#!/bin/sh
|
|
usage() {
|
|
printf 'usage: %s [-np] [-a alphabet] [-t type] [file ...]\n' \
|
|
"${0##*/}" >&2
|
|
exit 64
|
|
}
|
|
case "$(printf %s "${0##*/}" | tr A-Z a-z)" in
|
|
*16l*|*hexl*)
|
|
type=16l;;
|
|
*16*) type=16u;;
|
|
*32hexl*|*32x*l)
|
|
type=32x;;
|
|
*32hex*|*32x*)
|
|
type=32X;;
|
|
*32l*) type=32l;;
|
|
*32*) type=32u;;
|
|
*64s*) type=64s;;
|
|
*) type=64;;
|
|
esac
|
|
b16upper=0123456789ABCDEF
|
|
b16lower=0123456789abcdef
|
|
b32upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ234567
|
|
b32lower=abcdefghijklmnopqrstuvwxyz234567
|
|
b32hexupper=0123456789ABCDEFGHIJKLMNOPQRSTUV
|
|
b32hexlower=0123456789abcdefghijklmnopqrstuv
|
|
b64=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
|
|
b64safe=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_
|
|
alphabet=
|
|
pad=1
|
|
nl=1
|
|
while getopts a:npt: opt; do
|
|
case "$opt" in
|
|
a) alphabet="$OPTARG";;
|
|
n) nl=0;;
|
|
p) pad=0;;
|
|
t) case "$(printf %s "$OPTARG" | tr A-WYZ a-wyz)" in
|
|
16|16u|16upper)
|
|
type=16u;;
|
|
16l|16lower)
|
|
type=16l;;
|
|
32|32u|32upper)
|
|
type=32u;;
|
|
32l|32lower)
|
|
type=32l;;
|
|
32X) type=32X;;
|
|
32x) type=32x;;
|
|
64) type=64;;
|
|
64s|64safe)
|
|
type=64s;;
|
|
*) usage;;
|
|
esac
|
|
;;
|
|
*) usage;;
|
|
esac
|
|
done
|
|
shift $((OPTIND - 1))
|
|
case "$type" in
|
|
16u) alphabet="${alphabet:-$b16upper}"
|
|
bits=4;;
|
|
16l) alphabet="${alphabet:-$b16lower}"
|
|
bits=4;;
|
|
32u) alphabet="${alphabet:-$b32upper}"
|
|
bits=5;;
|
|
32l) alphabet="${alphabet:-$b32lower}"
|
|
bits=5;;
|
|
32X) alphabet="${alphabet:-$b32hexupper}"
|
|
bits=5;;
|
|
32x) alphabet="${alphabet:-$b32hexlower}"
|
|
bits=5;;
|
|
64) alphabet="${alphabet:-$b64}"
|
|
bits=6;;
|
|
64s) alphabet="${alphabet:-$b64safe}"
|
|
bits=6;;
|
|
*) usage;; # Unreachable
|
|
esac
|
|
od -An -tu1 -v -- "$@" | sed 's/^ *//' | tr -s ' ' '\n' |
|
|
sed 's/^00*//' | awk -vbits="$bits" -valphabet="$alphabet" \
|
|
-vnl="$nl" -vpad="$pad" '
|
|
function leftshift(a, b) {
|
|
return a * 2 ** b
|
|
}
|
|
function rightshift(a, b) {
|
|
return int(a / 2 ** b)
|
|
}
|
|
function mask(a, b) {
|
|
return a > 0 ? a % leftshift(1, b) : a
|
|
}
|
|
BEGIN {
|
|
split(alphabet, a, "")
|
|
} {
|
|
t = leftshift(t, 8) + $0
|
|
b += 8
|
|
while (b >= bits) {
|
|
b -= bits
|
|
printf "%s", a[rightshift(t, b) + 1]
|
|
t = mask(t, b)
|
|
count++
|
|
}
|
|
} END {
|
|
if (b > 0) {
|
|
printf "%s", a[leftshift(t, bits - b) + 1]
|
|
count++
|
|
}
|
|
if (pad && bits == 5)
|
|
for (count += 0; count % 8 != 0; count++)
|
|
printf "="
|
|
if (pad && bits == 6)
|
|
for (count += 0; count % 4 != 0; count++)
|
|
printf "="
|
|
if (nl)
|
|
print ""
|
|
}'
|