base64解码同时忽略括号

base64 decode while ignoring brackets

我正在尝试解码一个主要使用 base64 编码的文件。我想要做的是解码以下内容,同时仍然保持 [_*_].

example.txt

wq9cXyjjg4QpXy/Crwo=
[_NOTBASE64ED_]
aGkgdGhlcmUK
[_CONSTANT_]
SGVsbG8gV29ybGQhCg==

有时会是这种形式

aGkgdGhlcmUK[_CONSTANT_]SGVsbG8gV29ybGQhCg==

期望的输出

¯\_(ツ)_/¯
[_NOTBASE64ED_]
hi there
[_CONSTANT_]
Hello World!
hi there[_CONSTANT_]Hello World!

错误输出

¯\_(ツ)_/¯
4��!:�@�H\�B�8ԓ��[��ܛBbase64: invalid input

我试过的

base64 -di example.txt
base64 -d example.txt
base64 --wrap=0 -d -i example.txt

我尝试使用 grep -o 单独对 [_*_] 进行 base64。然后找到并
通过用数组进行奇怪的排列来替换它们,但我不能
让它工作。 base64ing 全部,然后解码。结果为双 base64ed 行。

文件显着缩小! 使用 base64 --wrap=0、while 循环和 if/else 语句进行编码。 [_*_]解码后还需要存在

您需要一个循环来读取每一行并测试它是 base64 还是非 base64,并适当地处理它。

while read -r line
do
    case "$line" in
        \[*\]) echo "$line" ;;
        *) base64 -d <<< "$line" ;;
    esac
done << example.txt

我相信有人有比这更聪明的解决方案。但是试试这个

#! /bin/bash

MYTMP1=""
function printInlineB64()
{
    local lines=($(echo  | sed -e 's/\[/\n[/g' -e 's/\]/]\n/g'))
    OUTPUT=""
    for line in "${lines[@]}"; do
        MYTMP1=$(base64 -d <<< "$line" 2>/dev/null)
        if [ "$?" != "0" ]; then
            OUTPUT="${OUTPUT}${line}"
        else
            OUTPUT="${OUTPUT}${MYTMP1}"
        fi;
    done
    echo "$OUTPUT"
}

MYTMP2=""
function printB64Line()
{
    local line=

    # not fully base64 line
    if [[ ! "$line" =~ ^[A-Za-z0-9+/=]+$ ]]; then 
        printInlineB64 "$line"
        return
    fi;

    # likely base64 line
    MYTMP2=$(base64 -d <<< "$line" 2>/dev/null)
    if [ "$?" != "0" ]; then
        echo $line
    else
        echo $MYTMP2
    fi;
}


FILE=
if [ -z "$FILE" ]; then
    echo "Please give a file name in argument" 
    exit 1;
fi;

while read line; do
    printB64Line "$line"
done < ${FILE}

这是输出

$ cat example.txt && echo "==========================" && ./base64.sh example.txt
wq9cXyjjg4QpXy/Crwo=
[_NOTBASE64ED_]
aGkgdGhlcmUK
[_CONSTANT_]
SGVsbG8gV29ybGQhCg==
==========================
¯\_(ツ)_/¯
[_NOTBASE64ED_]
hi there
[_CONSTANT_]
Hello World!

$ cat example2.txt && echo "==========================" && ./base64.sh example2.txt
aGkgdGhlcmUK[_CONSTANT_]SGVsbG8gV29ybGQhCg==
==========================
hi there[_CONSTANT_]Hello World!

我建议使用 sh 以外的其他语言,但这里有一个使用 cut 的解决方案。这将处理一行中有多个 [_constant_] 的情况。

#!/bin/bash

function decode() {
    local data=""
    local line=
    while [[ -n $line ]]; do
          data=$data$(echo $line | cut -d[ -f1 | base64 -d)
          const=$(echo $line | cut -d[ -sf2- | cut -d] -sf1)
          [[ -n $const ]] && data=$data[$const]
          line=$(echo $line | cut -d] -sf2-)
    done
    echo "$data"
}

while read -r line; do
    decode $line
done < example.txt

如果可以选择 Perl,您可以这样说:

perl -MMIME::Base64 -lpe '$_ = join("", grep {/^\[/ || chomp($_ = decode_base64($_)), 1} split(/(?=\[)|(?<=\])/))' example.txt

下面的代码等同于上面的代码,但为了解释的目的分成了几个步骤:

#!/bin/bash

perl -MMIME::Base64 -lpe '
    @ary = split(/(?=\[)|(?<=\])/, $_);
    foreach (@ary) {
        if (! /^\[/) {
            chomp($_ = decode_base64($_));
        }
    }
    $_ = join("", @ary);
' example.txt
  • -MMIME::Base64 选项加载 base64 编解码器模块。
  • -lpe 选项使 Perl bahave 像 AWK 一样循环输入行并隐式处理换行符。
  • 正则表达式(?=\[)|(?<=\])匹配base64块和被[...]包围的维护块之间的边界。
  • split函数在边界上将直线分割成块存储在数组中。
  • 然后遍历数组并解码 base64 编码的条目(如果找到)。
  • 最后将子字符串块合并成一行进行打印。