代码之家  ›  专栏  ›  技术社区  ›  Alex_DeLarge

“xxd-b”可以将数据转换为位字符串(例如:“a”01000001),但如何进行反向转换?

  •  2
  • Alex_DeLarge  · 技术社区  · 6 年前

    假设我们用utf8转换了一些内容,从中提取二进制文件,例如:

    echo "hello world" | xxd -p -b
    

    我们得到这个输出:

    00000000: 01101000 01100101 01101100 01101100 01101111 00100000  hello 
    00000006: 01110111 01101111 01110010 01101100 01100100 00001010  world.
    

    我们只需要一点点:

    01101000 01100101 01101100 01101100 01101111 00100000
    01110111 01101111 01110010 01101100 01100100 00001010
    

    有没有办法逆转这个过程并从这个位得到一个utf8(不是ascii!)字符串?

    1 回复  |  直到 6 年前
        1
  •  1
  •   pynexj    6 年前

    听起来你想转换 xxd -b 输出返回初始值 hello world 字符串?

    [STEP 103] # echo hello, world | xxd -b 
    00000000: 01101000 01100101 01101100 01101100 01101111 00101100  hello,
    00000006: 00100000 01110111 01101111 01110010 01101100 01100100   world
    0000000c: 00001010                                               .
    [STEP 104] # echo hello, world | xxd -b                 \
                 | sed -E -e 's/.*:(( [01]+){0,6}).*/\1/'   \
                          -e 's/ ([01]+)/ $((2#\1))/g'      \
                 | xargs bash -c 'eval printf %02x "$@" ' _ \
                 | xxd -p -r
    hello, world
    [STEP 105] #
    

    (您需要更新 sed 如果命令不支持 -E )

    一步一步地:

    [STEP 106] # echo xyz | xxd -b
    00000000: 01111000 01111001 01111010 00001010                    xyz.
    
    [STEP 107] # echo xyz | xxd -b | sed -E -e 's/.*:(( [01]+){0,6}).*/\1/' \
                                            -e 's/ ([01]+)/ $((2#\1))/g'
     $((2#01111000)) $((2#01111001)) $((2#01111010)) $((2#00001010))
    
    [STEP 108] # echo xyz | xxd -b | sed -E -e 's/.*:(( [01]+){0,6}).*/\1/' \
                                            -e 's/ ([01]+)/ $((2#\1))/g'    \
                 | xargs bash -c 'echo printf %02x "$@" ' DOLLAR0
    printf %02x $((2#01111000)) $((2#01111001)) $((2#01111010)) $((2#00001010))
    
    [STEP 109] # printf %02x $((2#01111000)) $((2#01111001)) $((2#01111010)) $((2#00001010))
    78797a0a
    
    [STEP 110] # echo xyz | xxd -b | sed -E -e 's/.*:(( [01]+){0,6}).*/\1/' \
                                            -e 's/ ([01]+)/ $((2#\1))/g'    \
                 | xargs bash -c 'eval printf %02x "$@" ' DOLLAR0
    78797a0a
    
    [STEP 111] # echo xyz | xxd -b | sed -E -e 's/.*:(( [01]+){0,6}).*/\1/' \
                                            -e 's/ ([01]+)/ $((2#\1))/g'    \
                 | xargs bash -c 'eval printf %02x "$@" ' DOLLAR0 | xxd -p -r
    xyz
    
    [STEP 112] #
    

    STEP 108 我用过 echo 而不是 eval 所以你可以看到 xargs 真的产生了。