Good day Stack you may think that this is the same question that has been answered before about the old base64, xxd, hexdump combination of commands to convert strings into base64, but instead of using external commands i'm trying to do the same only using builtins from bash like printf, read, echo... i am translating a C source from here and i have the encoding working so far but i have stumbled into a problematic C line
char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
...
char *p;
...
p = strchr(b64, c);
...
in[phase] = p - b64; //Problematic line
The thing is that p and b64 are char arrays and i don't understand what's doing the arithmetic expression with the two char arrays to obtain a number, it could be something like not or xor O_o. I'm still learning C and i don't know a lot.
This is what i have so far:
#!/bin/bash
declare -r b64=( {A..Z} {a..z} {0..9} {+,/} )
function ord() {
for i in {0..3}; do
printf '%d ' "'${1:$i:1}"
done
}
#TODO
function decodeblock() {
local out in=( $(ord $1) )
out[0]=$(( ${in[0]} << 2 | ${in[1]} >> 4 ))
out[1]=$(( ${in[1]} << 4 | ${in[2]} >> 2 ))
out[2]=$(( ${in[2]} << 6 | ${in[3]} >> 0 ))
printf "%s" "${out[@]}"
}
function encodeblock() {
local in=( $(ord "$1") ) len=$2 out index
index=$(( ${in[0]} >> 2 ))
out[0]=${b64[$index]}
index=$(( ((${in[0]} & 0x03) << 4) | ((${in[1]} & 0xf0) >> 4) ))
out[1]=${b64[$index]}
index=$(( ((${in[1]} & 0x0f) << 2) | ((${in[2]} & 0xc0) >> 6) ))
out[2]=$( (($len > 1)) && echo -n ${b64[$index]} || echo -n '=' )
index=$(( ${in[2]} & 0x3f ))
out[3]=$( (($len > 2)) && echo -n ${b64[$index]} || echo -n '=' )
printf "%s" "${out[@]}"
}
function b64_decode() {
local c i=0 phase=0 block p b64src="$1"
for (( i = 0 ; i < ${#b64src} ; i++)); do
c="${b64src:$i:1}"
[[ "$c" == '=' ]] && decodeblock "$b64src" && break
p="$c${b64[@]##*$c}"
if [[ -n "$p" ]]; then
#TODO
b64src[$phase]=
phase=$(( ($phase + 1) % 4 ))
if [[ $phase -eq 0 ]]; then
decodeblock "$b64src"
b64src=''
fi
((i++))
fi
done
}
function b64_encode() {
local block j=0 len clrstr="$1"
while [[ -n "${clrstr:$j:1}" ]]; do
len=0
for (( i = 0 ; i < 3 ; i++ )); do
block+="${clrstr:$j:1}"
[[ -n "${clrstr:$j:1}" ]] && { ((len++)) ; ((j++)); }
done
[[ -n $len ]] && encodeblock "${block[@]}" $len
block='' ; len=0
done
}
echo -n 'hello world' | base64 #DEBUG
b64_encode 'hello world' #DEBUG
b64_decode "$( b64_encode 'hello world' )"
Regards and thanks.