How to write binary data in Bash

前端 未结 6 2045
后悔当初
后悔当初 2021-01-20 05:54

Let us say there is a variable in bash script with value \"001\" how can i write this binary data into a file as bits (as \"001\" not \"1\") echo writes it as string but i w

相关标签:
6条回答
  • 2021-01-20 06:33

    Using bc (in CentOS 7.4):

    VALUE="3F"
    INPUT_BASE=16
    OUTPUT_BASE=2
    printf "%b\n" $(bc <<< "ibase=$INPUT_BASE; obase=$OUTPUT_BASE; $VALUE")
    

    RESULT: 111111

    If leading zeros are needed then:

    VALUE="3F"
    INPUT_BASE=16
    OUTPUT_BASE=2
    printf "%16b\n" $(bc <<< "ibase=$INPUT_BASE; obase=$OUTPUT_BASE; $VALUE") | sed 's^ ^0^g'
    

    RESULT: 0000000000111111

    Note the use of 16 in the printf format; change value to limit leading-zero count

    0 讨论(0)
  • 2021-01-20 06:38

    A couple of more general functions to output integers to a file:

    le16 () { # little endian 16 bit;  1st param: integer to 2nd param: file 
      v=`awk -v n=$1 'BEGIN{printf "%04X", n;}'`
      echo -n -e "\\x${v:2:2}\\x${v:0:2}" >> $2
    }
    
    le32 () { # 32 bit version
      v=`awk -v n=$1 'BEGIN{printf "%08X", n;}'`
      echo -n -e "\\x${v:6:2}\\x${v:4:2}\\x${v:2:2}\\x${v:0:2}" >> $2
    }
    
    0 讨论(0)
  • 2021-01-20 06:39

    Just use the %b in the printf:

    printf "%b" "\012"
    printf "%b" "\x0a"
    

    %b - Print the associated argument while interpreting backslash escapes in there

    so, above both prints binary value for the decimal 10.

    printf "%b" "\x0a" | od -bc
    

    output

    0000000   012                                                            
              \n      
    

    you can even mix

    printf "%b" "\12\xa\n" | od -bc
    
    0000000   012 012 012                                                    
              \n  \n  \n            
    
    0 讨论(0)
  • 2021-01-20 06:43

    You can write arbitrary bytes in hex or octal with:

    printf '\x03' > file   # Hex
    printf '\003' > file   # Octal
    

    If you have binary, it's a bit tricker, but you can turn it into octal with:

    printf '%o\n' "$((2#00000011))"
    

    which of course can be nested in the above:

    binary=00000011
    printf "\\$(printf '%o' "$((2#$binary))")" > file
    

    Note that this only works with up to 8 bits. If you want to write longer values, you have to split it up into groups of 8.

    0 讨论(0)
  • 2021-01-20 06:45

    Most often you want to write a pattern (for instance a 32 bit pattern).

    # Write 32 bits 5 times to a file 
    for i in {1..5}
    do
       printf '\x12\x34\xAC\xCD' >> binaryfile.bin
    done
    

    Another example:

    for i in {1..255}
    do
        hx=$( printf "%x" $i )
        output="\x$hx\x00\x00\x00"
        printf "%b" $output >> binaryfile.bin 
    done
    
    0 讨论(0)
  • 2021-01-20 06:49

    I needed this recently, someone might find it useful :

    #!/bin/bash
    
    # generate bitmasks for a C array
    
    # loop counter
    NUMBER=0
    MAX_BITMASK_LENGTH=8
    # max loop value : 2^8 = 255
    MAXVAL=$((2**MAX_BITMASK_LENGTH))
    # line number
    LINE=0
    
    # echo start of C array
    echo "    const long int bitmasks[${MAX_BITMASK_LENGTH}] = {"
    
    # loop over range of values
    while [ ${NUMBER} -le ${MAXVAL} ] ; do
    
        # use bc to convert to binary
        BINARY=`echo -e "obase=2\n${NUMBER}"| bc`
    
        # print current number, linenumber, binary
        printf "%12s, /* (%i) %8s */\n" ${NUMBER} ${LINE} ${BINARY}
    
        # increase loop value to next value
        NUMBER=$(((NUMBER*2)+1))
    
        # increment line number
        LINE=$((LINE+1))
    done
    
    # echo end of C array
    echo "        };"
    

    This outputs:

    $ ./generate_bitmasks.sh
        const long int bitmasks[8] = {
               0, /* (0)        0 */
               1, /* (1)        1 */
               3, /* (2)       11 */
               7, /* (3)      111 */
              15, /* (4)     1111 */
              31, /* (5)    11111 */
              63, /* (6)   111111 */
             127, /* (7)  1111111 */
             255, /* (8) 11111111 */
            };
    
    0 讨论(0)
提交回复
热议问题