【问题标题】:base64 decode while ignoring brackets忽略括号的 base64 解码
【发布时间】:2019-04-13 13:12:39
【问题描述】:

我正在尝试解码一个文件,该文件主要使用 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 块总是单行吗?
  • 并非总是如此,有时就像wq9cXyjjg4QpXy/Crwo=[_NOTBASE64ED_]aGkgdGhlcmUK
  • 这与您在示例中发布的内容有何不同?
  • 这是一个例子,其中 base64 块在同一行上,由 [_*_] 分隔,如果您的意思是如果一个 base64 块超长,它会进入新行,或者如果两个在同一行上没有分隔符的行,然后没有。

标签: bash encryption base64 sh decoding


【解决方案1】:

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

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

【讨论】:

  • 它似乎删除了wq9cXyjjg4QpXy/Crwo=[_NOTBASE64ED_]aGkgdGhlcmUK 示例中[ 之前的所有内容(我忘了在原始帖子中添加,现在添加了)。你也忘记了*)末尾的;;
  • 我写了这个答案,然后你在一行中间添加了[_NOTBASE64_] 的编辑。
  • 如果使用更强大的语言,比如perl,这可能会更容易。
【解决方案2】:

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

#! /bin/bash

MYTMP1=""
function printInlineB64()
{
    local lines=($(echo $1 | 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=$1

    # 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=$1
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!

【讨论】:

    【解决方案3】:

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

    #!/bin/bash
    
    function decode() {
        local data=""
        local line=$1
        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
    

    【讨论】:

      【解决方案4】:

      如果 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 像 AWK 一样循环遍历输入行并隐式处理换行符。
      • 正则表达式 (?=\[)|(?&lt;=\]) 匹配 base64 块和由 [...] 包围的维护块之间的边界。
      • split 函数将线划分为边界上的块并将它们存储在数组中。
      • 然后循环遍历数组并解码 base64 编码的条目(如果找到)。
      • 最后将子字符串块合并成一行打印。

      【讨论】:

        猜你喜欢
        • 2011-05-31
        • 2018-07-19
        • 1970-01-01
        • 1970-01-01
        • 2020-11-17
        • 1970-01-01
        • 1970-01-01
        • 2020-02-21
        • 2018-04-14
        相关资源
        最近更新 更多