Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Which is a good tool to convert ASCII to binary, and binary to ASCII?

I was hoping for something like:

$ 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

Or, more realistic:

$ 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

And also the reverse:

$ 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: I'm using bash

PS2: I hope I didn't get the wrong binary

share|improve this question
    
Can you post what you're ultimately going to want to do with this? Just b/c whatever solutions we provide will likely only work for a narrow use case, and I get the sense you'll be asking for something that you'll want to use in a more complex way, and any solutions provided will likely fail in that scenario. –  slm Nov 5 '13 at 15:33
    
@slm done, I edited the question –  RSFalcon7 Nov 5 '13 at 15:39
    
I take it you want to ignore the LF character output by echo. –  Stéphane Chazelas Nov 5 '13 at 15:57

3 Answers 3

up vote 10 down vote accepted
$ echo AB | perl -lpe '$_=unpack"B*"'
0100000101000010
$ echo 0100000101000010 | perl -lpe '$_=pack"B*",$_'
AB

With spaces:

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

(it assumes the input is in blocks of 8 bits (0-padded)).

share|improve this answer

You can use xxd to convert from ASCII and binary.

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

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

Converting bases

If you're looking to do just base conversions between Hex, Octal, & Dec I usually use the binary calculator command line tool (bc) to do such things. Note that bc is always very picky about the correct order of bases: you have to specify the resulting base (obase) first, then add your choice of ibase.

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

$ echo "obase=16; ibase=2; 1010" | bc
A
share|improve this answer
1  
That returns 1010 (10 == 0xa), not 65 == ASCII A –  Stéphane Chazelas Nov 5 '13 at 14:44
    
xxd would be nice, except it shows that first annoying column and the base input at the end of the line. –  RSFalcon7 Nov 5 '13 at 15:27
    
@RSFalcon7 - I know, you can pipe it to awk to get rid of it but it doesn't appear to have switches to disable this display. | awk '{print $2}'. There are other tools too. od & hexdump. I'm looking for another method using those. –  slm Nov 5 '13 at 15:30
    
@RSFalcon7 use the -p option to get 'pure' output –  Pureferret Jan 22 at 22:51
    
I use the xxd -b approach myself, however, one can't use xxd alone to convert binary back to ASCII. Todo so, I fear you would have to use something like printf 'obase=16;ibase=2;%s\n' "$n" | bc | xxd -p -r , with $n containing the number to convert, either as a long string of digits, or a strings of digits separated with semi-colons. If you can guarantee that $n fits into your shells's arithmetic type, then you may get away with printf '%x\n' $((2#$n)) | xxd -p -r –  Franki Dec 2 at 8:41

Using bc and 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
share|improve this answer
    
Looks like this only works for single char, am I wrong? –  RSFalcon7 Nov 5 '13 at 15:34
    
No, that's right, it's a single char –  Frederik Deweerdt Nov 5 '13 at 15:59
2  
@RSFalcon7 edited to work with multiple chars –  Frederik Deweerdt Nov 5 '13 at 16:10

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.