Инструменты преобразования ASCII в двоичные и двоичные в ASCII?

31

Какой хороший инструмент для преобразования ASCII в двоичный файл и двоичный файл в ASCII?

Я надеялся на что-то вроде:

$ 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

Или более реалистично:

$ 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

А также наоборот:

$ 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: я использую Bash

PS2: я надеюсь, что я не получил неправильный двоичный файл

RSFalcon7
источник
Можете ли вы опубликовать, что вы в конечном итоге захотите сделать с этим? Просто б / у, какие бы решения мы ни предлагали, скорее всего, будет работать только для узкого варианта использования, и я понимаю, что вы будете просить что-то, что вы захотите использовать более сложным способом, и любые предоставленные решения, скорее всего, потерпят неудачу в этом сценарии.
SLM
@ сделано, я отредактировал вопрос
RSFalcon7
Я так понимаю, вы хотите игнорировать вывод символов LF с помощью echo.
Стефан Шазелас
Лучший способ понять это - все двоично. То, что вы пытаетесь сделать, - это создать строку двоичных цифр ascii, которые представляют двоичный код исходного сообщения ascii codded. Следовательно, не имеет значения, что оригинал имеет кодировку ascii (ну почти так же долго, как он есть). Теперь вам просто нужен инструмент, который может печатать двоичный файл в виде текста. (уже есть ответ, чтобы рассказать вам, как).
ctrl-alt-delor

Ответы:

36
$ echo AB | perl -lpe '$_=unpack"B*"'
0100000101000010
$ echo 0100000101000010 | perl -lpe '$_=pack"B*",$_'
AB
  • -e expressionоцените данное выражение как perlкод
  • -p: sedРежим. Выражение вычисляется для каждой строки ввода, с содержанием строки , хранящейся в $_переменной и напечатанной после оценки экспрессии .
  • -l: даже больше похоже sed: вместо полной строки, только содержимое строки (то есть без разделителя строки) находится в $_(и новая строка добавляется обратно на выходе). Так perl -lpe codeработает, sed codeза исключением того, что это perlкод, а не sedкод.
  • unpack "B*"работает с $_переменной по умолчанию и извлекает ее содержимое в виде строки битов, начиная с старшего бита первого байта до младшего бита последнего байта.
  • packделает наоборот unpack. Смотрите perldoc -f packподробности.

С пробелами:

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

(предполагается, что входные данные в блоках по 8 бит (с добавлением 0)).

С помощью unpack "(B8)*"мы извлекаем 8 битов за раз и соединяем получающиеся строки с пробелами с join " ".

Стефан Шазелас
источник
Большое спасибо. Я немного знаком с Perl, но расширенные детали будут очень полезны для тех, кто совсем новичок в Perl.
Yokai
23

Вы можете использовать xxdдля преобразования из ASCII и двоичного файла.

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

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

Конвертирующие базы

Если вы хотите просто выполнить базовые преобразования между шестнадцатеричным, октальным и декабрьским значениями, я обычно использую базовый инструмент командной строки калькулятора ( bc) для таких целей. Обратите внимание, что bcвсегда очень требователен к правильному порядку баз: obaseсначала нужно указать результирующую базу ( ), а затем добавить свой выбор ibase.

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

$ echo "obase=16; ibase=2; 1010" | bc
A
SLM
источник
xxdбыло бы неплохо, за исключением того, что показывает, что первый раздражающий столбец и базовый ввод в конце строки.
RSFalcon7
@ RSFalcon7 - я знаю, вы можете передать его, чтобы awkизбавиться от него, но на нем нет переключателей для отключения этого дисплея. | awk '{print $2}', Есть и другие инструменты. od& hexdump. Я ищу другой метод, использующий их.
SLM
1
@ RSFalcon7 используйте -pопцию для получения «чистого» вывода
Pureferret
Я использую xxd -bподход сам, однако, нельзя использовать xxdодин, чтобы преобразовать двоичный файл обратно в ASCII. Кроме того, я боюсь, что вам придется использовать что-то вроде printf 'obase=16;ibase=2;%s\n' "$n" | bc | xxd -p -r$ n, содержащего число для преобразования, либо в виде длинной строки цифр, либо в виде строки цифр, разделенных точкой с запятой. Если вы можете гарантировать, что $ n вписывается в арифметический тип ваших оболочек, то вы можете сойти с рукprintf '%x\n' $((2#$n)) | xxd -p -r
Franki
Если только вы не можете использовать что-то вроде perl / python
Franki
8

Использование bc и 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
Фредерик Дьюердт
источник
5

Оболочка решение для преобразования двоичного в 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
источник
2
Это не чисто решение для оболочки. sed, trи bcявляются внешними программами, вызываемыми в сценарии оболочки.
Йокай
4

В питоне

Для символов ASCII в диапазоне [ -~] на Python 2:

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

В обратном порядке:

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

В Python 3.2+:

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

В обратном порядке:

>>> n = int('0b110100001100101011011000110110001101111', 2)
>>> n.to_bytes((n.bit_length() + 7) // 8, 'big').decode()
'hello'
Serv-вкл
источник
2

Использование 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'")

Сохранено как "bin2ascii", например:

$ bin2ascii -a "Hello, world!"
1001000011001010110110001101100011011110010110000100000011101110110111101110010011011000110010000100001

$ bin2ascii -b 1001000011001010110110001101100011011110010110000100000011101110110111101110010011011000110010000100001  
Hello, world!
Vishtar
источник
0

Кодирование двоичного файла с помощью base64

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

Декодирование base64

$ echo "VGhpcyBpcyBhIGJpbmFyeSBtZXNzYWdlCg==" | base64 -d
This is a binary message
подобно
источник