Unix command/s or Tcl proc to convert hex data to binary with output 1 bit per line

116 views Asked by At

I have a plain text file with hex data information (32-bit word per line). Example :

cafef00d
deadbeef

That I need to convert to this :

11001010111111101111000000001101
11011110101011011011111011101111

BUT with 1 bit per line only. Starting from the LSB of the first 32-bit hex and so on. Final output file will be :

1
0
1
1
... and so on

Is there a unix command/s or can I do this in a Tcl proc ?

3

There are 3 answers

2
Donal Fellows On BEST ANSWER

A solution...

Assuming you've read the file into a string, the first thing is to convert the hex strings into numbers expressed in binary, LSB first. There's a few ways to do it, here's one (I like scan and format):

set binaryData [lmap hexValue $inputData {
    scan $hexValue "%x" value
    string reverse [format "%b" $value]
}]

For your input, that produces:

10110000000011110111111101010011 11110111011111011011010101111011

We can then convert that to be one digit per line with this:

set oneDigitPerLine [join [split [join $binaryData ""] ""] "\n"]

The innermost join gets rid of the whitespace, the split breaks it up into characters, and the outer join inserts the newline separators. (I'll not produce the result here.)

0
sharvian On

If you want to do it with linux commands, try the following:

tac: reverse text lines in a file

fold -w 1: fold a text file, column width 1

sed: replace strings

tac input_file | \
fold -w 1 | \
sed -e 's/0/0000/' | \
sed -e 's/1/0001/' | \
sed -e 's/2/0010/' | \
sed -e 's/3/0011/' | \
sed -e 's/4/0100/' | \
sed -e 's/5/0101/' | \
sed -e 's/6/0110/' | \
sed -e 's/7/0111/' | \
sed -e 's/8/1000/' | \
sed -e 's/9/1001/' | \
sed -e 's/a/1010/' | \
sed -e 's/b/1011/' | \
sed -e 's/c/1100/' | \
sed -e 's/d/1101/' | \
sed -e 's/e/1110/' | \
sed -e 's/f/1111/' | \
told -w 1 | \
tac
0
Shawn On

Another way, using a perl one-liner:

$ perl -nE 'say for split "", reverse sprintf("%032b", hex)' < input.txt
1
0
1
1
...

For each line, converts from a base-16 string to a number and turns that into a binary string, and then prints each individual character on its own line.