#!/bin/bash # Base64 decoder - pure bash function # 2024 F-Hauri.ch - felix@f-hauri.ch # Licensed under terms of GPL v3. www.gnu.org # shellcheck disable=SC2154 # not assigned 'myVar' ?? shopt -s extglob declare -a B64=( {A..Z} {a..z} {0..9} + / '=' ) declare -Ai 'B64R=()' for i in "${!B64[@]}"; do B64R["${B64[i]}"]=i%64; done # shellcheck disable=SC2034 # Unused 'B64R' ?? declare -r B64R unset B64 b64dec() { local _4B _Tail _hVal _v _opt OPTIND local -i iFd _24b _ar while getopts "av:" _opt; do case $_opt in a) _ar=1;; v) _v=${OPTARG};; *) return 1;; esac; done shift $((OPTIND-1)) if [[ $_v ]];then local -n _res=${_v}; else local _res; fi if [[ $1 ]]; then exec {iFd}<<<"$1" # Open Input FD from string else exec {iFd}<&0 ; fi # Open Input FD from STDIN _res=() while read -rn4 -u $iFd _4B; do if [[ "$_4B" ]]; then _Tail=$_4B _24b=" B64R['${_4B::1}'] << 18 | B64R['${_4B:1:1}'] << 12 | B64R['${_4B:2:1}'] << 6 | B64R['${_4B:3:1}'] " printf -v _hval %02x\ $((_24b>>16)) $((_24b>>8&255)) $((_24b&255)) read -ra _hval <<<"$_hval" _res+=("${_hval[@]}") fi done exec {iFd}<&- _Tail=${_Tail##*([^=])} while [[ $_Tail ]]; do unset "_res[-1]" _Tail=${_Tail:1} done ((_ar==0)) && printf -v _res %b "${_res[@]/#/\\x}" && _res=("${_res[0]}") [[ -z $_v ]] && echo "${_res[@]}" } ## Exit here if script is sourced [[ $0 = "${BASH_SOURCE[0]}" ]] || { true;return 0;} cat <<"eoUsage" Usage: b64dec [-v varname] [-a] [string] -v VARNAME Assign result to $VARNAME instead of print them on STDOUT -a Return an array of hexadecimal values for hangling binary If no "string" are submited as argument, b64dec will wait for input on STDIN. eoUsage set -v echo -n '1 ' b64dec 'dGVzdA==' echo -n '2 ' b64dec <<<'dGVzdA==' b64dec -v myVar 'dGVzdA==' echo "3 $myVar" b64dec -av myVar 'dGVzdA==' printf -v str %b "${myVar[@]/#/\\x}" printf '4 %s <= [%s].\n' "$str" "${myVar[*]}" lstr='H4sIAAAAAAACA/NIzcnJVyjPL8pJU' for str in ${lstr}{eQCAEHkqbINAAAA,VTkAgAYI85FDgAAAA==,VRU5AIAj62OVw8AAAA=}; do b64dec -v test -a <<<"$str" zcat < <(printf %b "${test[@]/#/\\x}") done b64dec -av myVar < <( seq 1 100 | column | gzip | base64 ) gzip -d < <(printf %b "${myVar[@]/#/\\x}")