Skip to content

Instantly share code, notes, and snippets.

@td-shi
Last active March 15, 2021 13:55
Show Gist options
  • Save td-shi/f3e30a55e52ea727a21afa7eb49100fb to your computer and use it in GitHub Desktop.
Save td-shi/f3e30a55e52ea727a21afa7eb49100fb to your computer and use it in GitHub Desktop.
Encode and decode to or from base 64.
#!/bin/sh
# -*- coding:utf-8 posix -*-
# === Coding shell scripting Memo ==============================================
# ${<name>#<pattern>} :: matching delete with shortest by forword.
# ${<name>##<pattern>} :: matching delete with longest by forword.
# ${<name>%<pattern>} :: matching delete with shortest by backword.
# ${<name>%%<pattern>} :: mathing delete with longest by backword.
# ${<name>/<before>/<after>} :: replace only first matching.
# ${<name>//<before>/<after>} :: replace all matching.
# ${<name>:-<value>} :: if no yet set value, return value.
# ${<name>:=<value>} :: if no yet set value, return value and set.
# ". <shell script>" is to keep current shell and take over environment.
# === Initialize shell environment =============================================
#set -u # Just stop undefined values.
#set -e # Just stop error.
#set -x # Debug running command.
umask 0022
export LC_ALL=C
export LANG=C
PATH="$(command -p getconf PATH 2>/dev/null)${PATH+:}${PATH-}"
case $PATH in :*) PATH=${PATH#?};; esac
export PATH # or PATH="<add dir>${PATH+:}${PATH-}"
export UNIX_STD=2003 # to make HP-UX conform to POSIX
# === Define the functions for printing usage and error message ================
usage_and_exit(){
cat <<-"USAGE" 1>&2
# About
base64.sh is encode and decode to or from base 64.
# Usage
## Command
base64.sh [options] [file]
The standard input shall be used, if no file operand is specified.
## Options
- -h |--help |--version
+ This help.
- -d
+ Decode base 64.
base64url? 'base64.sh | tr "/+" "_-"' or 'cat <file> | tr "_-" "/+" | base64.sh -d' .
# Version
2021-03-10T18:35:41 0.01 [Search](https://gist.github.com/search?q=user%3Atd-shi+filename%3A.sh+base64)
# LICENSE
[CC0(Public domain)](https://creativecommons.org/publicdomain/zero/1.0/legalcode)
# Author
2021 TD
USAGE
exit 1
}
error_exit() {
${2+:} false && echo "${0##*/}: $2" 1>&2
exit "$1"
}
# === Initialize parameters ====================================================
SED_LF=$(printf '\\\n_')
SED_LF=${SED_LF%_}
IN_FILE=''
CODEC="e"
# === Confirm that the required commands exist =================================
# === Print usage and exit if one of the help options is set ===================
case "$# ${1:-}" in
'1 -h'|'1 --help'|'1 --version') usage_and_exit;;
esac
# === Read options =============================================================
while :; do
case "${1:-}" in
-d)
CODEC="d"
shift
break
;;
--|-)
break
;;
--*|-*)
error_exit 1 'Invalid option.'
;;
*)
break
;;
esac
done
# === Require parameters check =================================================
# === Last parameter ===========================================================
case $# in
0) : ;;
1) IN_FILE=$1 ;;
*) error_exit 1 'Too many args.' ;;
esac
if [ "_$IN_FILE" = '_' ] ||
[ "_$IN_FILE" = '_-' ] ||
[ "_$IN_FILE" = '_/dev/stdin' ] ||
[ "_$IN_FILE" = '_/dev/fd/0' ] ||
[ "_$IN_FILE" = '_/proc/self/fd/0' ] ; then
IN_FILE=''
elif [ -f "$IN_FILE" ] ||
[ -c "$IN_FILE" ] ||
[ -p "$IN_FILE" ] ; then
[ -r "$IN_FILE" ] || error_exit 1 'Cannot open the file: '"$IN_FILE"
else
usage_and_exit
fi
case "$IN_FILE" in ''|-|/*|./*|../*) :;; *) IN_FILE="./$IN_FILE";; esac
# === Define funcitons =========================================================
# === Main routine =============================================================
# shellcheck disable=SC2002
case "-${CODEC}" in
-d)
cat ${IN_FILE:+"$IN_FILE"} |\
tr -d "=" |\
sed "s/[[:blank:]]//g" |\
tr "01" "<>" |\
sed "s/./&${SED_LF}/g" |\
sed "/^$/d" |\
paste -d "" - - - - |\
sed "s:/:111111:g" |\
sed "s:+:111110:g" |\
sed "s:9:111101:g" |\
sed "s:8:111100:g" |\
sed "s:7:111011:g" |\
sed "s:6:111010:g" |\
sed "s:5:111001:g" |\
sed "s:4:111000:g" |\
sed "s:3:110111:g" |\
sed "s:2:110110:g" |\
sed "s:>:110101:g" |\
sed "s:<:110100:g" |\
sed "s:z:110011:g" |\
sed "s:y:110010:g" |\
sed "s:x:110001:g" |\
sed "s:w:110000:g" |\
sed "s:v:101111:g" |\
sed "s:u:101110:g" |\
sed "s:t:101101:g" |\
sed "s:s:101100:g" |\
sed "s:r:101011:g" |\
sed "s:q:101010:g" |\
sed "s:p:101001:g" |\
sed "s:o:101000:g" |\
sed "s:n:100111:g" |\
sed "s:m:100110:g" |\
sed "s:l:100101:g" |\
sed "s:k:100100:g" |\
sed "s:j:100011:g" |\
sed "s:i:100010:g" |\
sed "s:h:100001:g" |\
sed "s:g:100000:g" |\
sed "s:f:011111:g" |\
sed "s:e:011110:g" |\
sed "s:d:011101:g" |\
sed "s:c:011100:g" |\
sed "s:b:011011:g" |\
sed "s:a:011010:g" |\
sed "s:Z:011001:g" |\
sed "s:Y:011000:g" |\
sed "s:X:010111:g" |\
sed "s:W:010110:g" |\
sed "s:V:010101:g" |\
sed "s:U:010100:g" |\
sed "s:T:010011:g" |\
sed "s:S:010010:g" |\
sed "s:R:010001:g" |\
sed "s:Q:010000:g" |\
sed "s:P:001111:g" |\
sed "s:O:001110:g" |\
sed "s:N:001101:g" |\
sed "s:M:001100:g" |\
sed "s:L:001011:g" |\
sed "s:K:001010:g" |\
sed "s:J:001001:g" |\
sed "s:I:001000:g" |\
sed "s:H:000111:g" |\
sed "s:G:000110:g" |\
sed "s:F:000101:g" |\
sed "s:E:000100:g" |\
sed "s:D:000011:g" |\
sed "s:C:000010:g" |\
sed "s:B:000001:g" |\
sed "s:A:000000:g" |\
sed "s/[01][01][01][01][01][01][01][01]/& /g" |\
sed "s/ [01][01]$//" |\
sed "s/ [01][01][01][01]$//" |\
sed "s/^[01][01][01][01][01][01]$//" |\
sed "s/\([01][01]\)\([01][01][01]\)\([01][01][01]\)/0\1 \2 \3 /g" |\
sed "s/111/7/g" |\
sed "s/110/6/g" |\
sed "s/101/5/g" |\
sed "s/100/4/g" |\
sed "s/011/3/g" |\
sed "s/010/2/g" |\
sed "s/001/1/g" |\
sed "s/000/0/g" |\
tr -d " " |\
paste -d "" - - - - - - - - |\
sed 's/.../\\\\&/g' |\
xargs -n 1 printf
;;
*)
# Convert 2char hex.
# od -A n -t x1 -v
# hexdump -e '16/1 " %02x" "\n"' -v
cat ${IN_FILE:+"$IN_FILE"} |\
od -A n -t x1 -v |\
paste -d "" - - - |\
sed "s/0/</g" |\
sed "s/1/0001/g" |\
sed "s/2/0010/g" |\
sed "s/3/0011/g" |\
sed "s/4/0100/g" |\
sed "s/5/0101/g" |\
sed "s/6/0110/g" |\
sed "s/7/0111/g" |\
sed "s/8/1000/g" |\
sed "s/9/1001/g" |\
sed "s/a/1010/g" |\
sed "s/b/1011/g" |\
sed "s/c/1100/g" |\
sed "s/d/1101/g" |\
sed "s/e/1110/g" |\
sed "s/f/1111/g" |\
sed "s/A/1010/g" |\
sed "s/B/1011/g" |\
sed "s/C/1100/g" |\
sed "s/D/1101/g" |\
sed "s/E/1110/g" |\
sed "s/F/1111/g" |\
sed "s/</0000/g" |\
tr -d " " |\
sed "s/[01][01][01][01][01][01]/& /g" |\
sed "s/^[01][01]$/&0000/g" |\
sed "s/ [01][01]$/&0000/g" |\
sed "s/^[01][01][01][01]$/&00/g" |\
sed "s/ [01][01][01][01]$/&00/g" |\
sed "s:111111:/:g" |\
sed "s:111110:+:g" |\
sed "s:111101:9:g" |\
sed "s:111100:8:g" |\
sed "s:111011:7:g" |\
sed "s:111010:6:g" |\
sed "s:111001:5:g" |\
sed "s:111000:4:g" |\
sed "s:110111:3:g" |\
sed "s:110110:2:g" |\
sed "s:110101:1:g" |\
sed "s:110100:0:g" |\
sed "s:110011:z:g" |\
sed "s:110010:y:g" |\
sed "s:110001:x:g" |\
sed "s:110000:w:g" |\
sed "s:101111:v:g" |\
sed "s:101110:u:g" |\
sed "s:101101:t:g" |\
sed "s:101100:s:g" |\
sed "s:101011:r:g" |\
sed "s:101010:q:g" |\
sed "s:101001:p:g" |\
sed "s:101000:o:g" |\
sed "s:100111:n:g" |\
sed "s:100110:m:g" |\
sed "s:100101:l:g" |\
sed "s:100100:k:g" |\
sed "s:100011:j:g" |\
sed "s:100010:i:g" |\
sed "s:100001:h:g" |\
sed "s:100000:g:g" |\
sed "s:011111:f:g" |\
sed "s:011110:e:g" |\
sed "s:011101:d:g" |\
sed "s:011100:c:g" |\
sed "s:011011:b:g" |\
sed "s:011010:a:g" |\
sed "s:011001:Z:g" |\
sed "s:011000:Y:g" |\
sed "s:010111:X:g" |\
sed "s:010110:W:g" |\
sed "s:010101:V:g" |\
sed "s:010100:U:g" |\
sed "s:010011:T:g" |\
sed "s:010010:S:g" |\
sed "s:010001:R:g" |\
sed "s:010000:Q:g" |\
sed "s:001111:P:g" |\
sed "s:001110:O:g" |\
sed "s:001101:N:g" |\
sed "s:001100:M:g" |\
sed "s:001011:L:g" |\
sed "s:001010:K:g" |\
sed "s:001001:J:g" |\
sed "s:001000:I:g" |\
sed "s:000111:H:g" |\
sed "s:000110:G:g" |\
sed "s:000101:F:g" |\
sed "s:000100:E:g" |\
sed "s:000011:D:g" |\
sed "s:000010:C:g" |\
sed "s:000001:B:g" |\
sed "s:000000:A:g" |\
tr -d " " |\
sed "s/..../&${SED_LF}/g" |\
sed "/^$/d" |\
sed "s/^...$/&=/g" |\
sed "s/^..$/&==/g" |\
sed "s/^.$/&===/g" |\
paste -d "" - - - - - - - - - - - - - - - -
;;
esac
# === End shell script =========================================================
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment