Ferramentas de conversão ASCII para binário e binário para ASCII?

31

Qual é uma boa ferramenta para converter ASCII em binário e binário em ASCII?

Eu esperava algo como:

$ echo --binary "This is a binary message"
01010100 01101000 01101001 01110011 00100000 01101001 01110011 00100000 01100001 00100000 01100010 01101001 01101110 01100001 01110010 01111001 00100000 01101101 01100101 01110011 01110011 01100001 01100111 01100101

Ou, mais realista:

$ echo "This is a binary message" | ascii2bin
01010100 01101000 01101001 01110011 00100000 01101001 01110011 00100000 01100001 00100000 01100010 01101001 01101110 01100001 01110010 01111001 00100000 01101101 01100101 01110011 01110011 01100001 01100111 01100101

E também o contrário:

$ echo "01010100 01101000 01101001 01110011 00100000 01101001 01110011 00100000 01100001 00100000 01100010 01101001 01101110 01100001 01110010 01111001 00100000 01101101 01100101 01110011 01110011 01100001 01100111 01100101" | bin2ascii
This is a binary message

PS: Estou usando o bash

PS2: Espero não ter entendido o binário errado

RSFalcon7
fonte
Você pode postar o que você vai querer fazer com isso? Apenas b / c, independentemente das soluções que fornecemos, provavelmente funcionará apenas para um caso de uso restrito, e tenho a sensação de que você estará pedindo algo que deseje usar de uma maneira mais complexa, e todas as soluções fornecidas provavelmente falharão. nesse cenário.
slm
@slm feito, eu editei a pergunta
RSFalcon7
Suponho que você queira ignorar a saída de caracteres LF por echo.
Stéphane Chazelas
A melhor maneira de entender isso é que tudo é binário. O que você está tentando fazer é produzir uma sequência ASCII de dígitos binários que representam o binário da mensagem codificada ASCII original. Portanto, é irrelevante que o original seja codificado em ASCII (bem, quase, desde que seja). Agora você só precisa de uma ferramenta que pode imprimir o binário como texto. (já existem respostas para lhe dizer como).
ctrl-alt-Delor

Respostas:

36
$ echo AB | perl -lpe '$_=unpack"B*"'
0100000101000010
$ echo 0100000101000010 | perl -lpe '$_=pack"B*",$_'
AB
  • -e expressionavaliar a expressão dada como perlcódigo
  • -p: sedmode. A expressão é avaliada para cada linha de entrada, com o conteúdo da linha armazenada na $_variável e impressa após a avaliação da expressão .
  • -l: ainda mais como sed: em vez da linha completa, apenas o conteúdo da linha (ou seja, sem o delimitador de linha) está $_(e uma nova linha é adicionada novamente na saída). Então, perl -lpe codefunciona como sed codeexceto que é um perlcódigo em oposição ao sedcódigo.
  • unpack "B*" trabalha no $_ variável por padrão e extrai seu conteúdo como uma sequência de bits que caminha do bit mais alto do primeiro byte até o bit mais baixo do último byte.
  • packfaz o inverso de unpack. Veja perldoc -f packpara detalhes.

Com espaços:

$ echo AB | perl -lpe '$_=join " ", unpack"(B8)*"'
01000001 01000010
$ echo 01000001 01000010 | perl -lape '$_=pack"(B8)*",@F'
AB

(assume que a entrada está em blocos de 8 bits (preenchido com 0)).

Com unpack "(B8)*", extraímos 8 bits de cada vez e juntamos as cadeias resultantes com espaços com join " ".

Stéphane Chazelas
fonte
Muito Obrigado. Eu estou um pouco familiarizado com o perl, mas os detalhes estendidos serão muito úteis para aqueles completamente novos no perl.
Yokai
23

Você pode usar xxdpara converter de ASCII e binário.

$ echo -n "A" | xxd -b
0000000: 01000001                                               A

$ echo -n "A" | xxd -b | awk '{print $2}'
01000001

Conversão de bases

Se você deseja fazer apenas conversões básicas entre Hex, Octal e Dec, geralmente uso a ferramenta básica de linha de comando da calculadora ( bc) para fazer essas coisas. Observe que bcsempre é muito exigente quanto à ordem correta das bases: você deve especificar a base ( obase) resultante primeiro e depois adicionar sua opção ibase.

$ echo "obase=2; ibase=16; A" | bc
1010

$ echo "obase=16; ibase=2; 1010" | bc
A
slm
fonte
xxdseria bom, exceto que mostra a primeira coluna irritante e a entrada de base no final da linha.
precisa saber é o seguinte
@ RSFalcon7 - Eu sei, você pode canalizá-lo para awkse livrar dele, mas ele não parece ter opções para desativar essa exibição. | awk '{print $2}'. Existem outras ferramentas também. od& hexdump. Estou procurando outro método usando esses.
Slm
11
@ RSFalcon7 usar a -popção de obter uma saída 'puro'
Pureferret
Eu mesmo uso a xxd -babordagem, no entanto, não se pode usar xxdsozinho para converter o binário novamente em ASCII. De qualquer forma, temo que você precise usar algo como printf 'obase=16;ibase=2;%s\n' "$n" | bc | xxd -p -r, com $ n contendo o número a ser convertido, como uma longa sequência de dígitos ou uma sequência de dígitos separados por ponto e vírgula. Se você pode garantir que $ n se encaixa no tipo aritmético de suas conchas, você pode se safar #printf '%x\n' $((2#$n)) | xxd -p -r
Franki
A menos que você pode usar algo como perl / python
Franki
8

Usando bc e bash:

#!/bin/bash

chrbin() {
        echo $(printf \\$(echo "ibase=2; obase=8; $1" | bc))
}

ordbin() {
  a=$(printf '%d' "'$1")
  echo "obase=2; $a" | bc
}

ascii2bin() {
    echo -n $* | while IFS= read -r -n1 char
    do
        ordbin $char | tr -d '\n'
        echo -n " "
    done
}

bin2ascii() {
    for bin in $*
    do
        chrbin $bin | tr -d '\n'
    done
}
ascii2bin "This is a binary message"
bin2ascii 01010100 01101000 01101001 01110011 00100000 01101001 01110011 00100000 01100001 00100000 01100010 01101001 01101110 01100001 01110010 01111001 00100000 01101101 01100101 01110011 01110011 01100001 01100111 01100101
Frederik Deweerdt
fonte
5

Solução Shell para converter binários em ascii:

bin2ascii() { { tr -cd 01 | fold -w8; echo; } | sed '1i obase=8; ibase=2' | bc | sed 's/^/\\/' | tr -d '\n' | xargs -0 echo -e; }
n.caillou
fonte
2
Esta não é uma solução pura de casca. sed,, tre bcsão programas externos chamados no shell script.
Yokai
4

Em Python

Para caracteres ASCII no intervalo [ -~]do Python 2:

>>> import binascii
>>> bin(int(binascii.hexlify('hello'), 16))
'0b110100001100101011011000110110001101111'

Ao contrário:

>>> n = int('0b110100001100101011011000110110001101111', 2)
>>> binascii.unhexlify('%x' % n)
'hello'

No Python 3.2+:

>>> bin(int.from_bytes('hello'.encode(), 'big'))
'0b110100001100101011011000110110001101111'

Ao contrário:

>>> n = int('0b110100001100101011011000110110001101111', 2)
>>> n.to_bytes((n.bit_length() + 7) // 8, 'big').decode()
'hello'
serv-inc
fonte
2

Usando Python 3:

#!/usr/bin/env python3

import sys


if __name__ == "__main__":
    if len(sys.argv) != 1 and len(sys.argv) <= 3:
        if sys.argv[1] in ('-b', '--binary'):
            n = int(sys.argv[2].replace(' ', ''), 2)
            print(n.to_bytes((n.bit_length() + 7) // 8, 'big').decode())
        if sys.argv[1] in ('-a', '--ascii'):
            print((bin(int.from_bytes(sys.argv[2].encode(), 'big')))[2:])
    else:
        print("Example: decode -b '10000001'")

Salvo como "bin2ascii", por exemplo:

$ bin2ascii -a "Hello, world!"
1001000011001010110110001101100011011110010110000100000011101110110111101110010011011000110010000100001

$ bin2ascii -b 1001000011001010110110001101100011011110010110000100000011101110110111101110010011011000110010000100001  
Hello, world!
Vishtar
fonte
0

Codificando binário por base64

$ echo "This is a binary message" | base64
VGhpcyBpcyBhIGJpbmFyeSBtZXNzYWdlCg==

Decodificando base64

$ echo "VGhpcyBpcyBhIGJpbmFyeSBtZXNzYWdlCg==" | base64 -d
This is a binary message
Gostar
fonte