Перевести исходный код C-кодировщика base64 в встроенный скрипт bash - PullRequest
0 голосов
/ 25 июня 2018

Добрый день, стек Вы можете подумать, что это тот же вопрос, на который ранее уже был дан ответ о старой комбинации base64, xxd, hexdump команд для преобразования строк в base64, но вместо использования внешних команд iя пытаюсь сделать то же самое только с помощью встроенных команд из bash, таких как printf, read, echo ... я переводю источник C из здесь , и у меня пока работает кодировка, ноя наткнулся на проблемную C-строку

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

Дело в том, что p и b64 являются массивами символов, и я не понимаю, что делает арифметическое выражение с двумя массивами символов для полученияномер, это может быть что-то вроде нет или xor 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 $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' )"

С уважением и благодарностью.

1 Ответ

0 голосов
/ 25 июня 2018

strchr(b64, c) ищет символ c в строке b64 и возвращает указатель на него, если найден; вычитание b64 из этого значения просто дает индекс символа внутри b64.

Короче говоря, он получает индекс c в b64. Что касается того, как реализовать это в оболочке, здесь вы можете найти некоторое вдохновение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...