将 base64 编码器 C 源代码翻译成 bash 内置脚本

Translate base64 encoder C source code to bash builtins script

你好 Stack 你可能会认为这是关于旧的 base64xxdhexdump 将字符串转换为 base64 的命令组合的相同问题,但我没有使用外部命令,而是尝试仅使用来自 bash 的内置命令来做同样的事情,例如 printfreadecho...我正在翻译 C来自 here 的来源,到目前为止我的编码工作正常,但我无意中遇到了有问题的 C 行

char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
...
char *p;
...
p = strchr(b64, c);
...
in[phase] = p - b64; //Problematic line

问题是 pb64 是 char 数组,我不明白用这两个 char 数组进行算术表达式以获得数字的原因是什么,它可能不是或异或 O_o。我还在学习C,我知道的不多

这是我目前拥有的:

#!/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 ) )
    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 "") ) len= 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=""
    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=""
    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' )"

问候和感谢。

strchr(b64, c) 将字符 c 搜索到字符串 b64 中,如果找到则 returns 指向它的指针;从这个值中减去 b64 只会得到 b64 中字符的索引。

长话短说,它正在 b64 中获取 c 的索引。至于如何在shell、here中实现这个你可能会找到一些灵感。