Convert binary data to hexadecimal in a shell script

后端 未结 8 1504
日久生厌
日久生厌 2020-12-13 05:59

I want to convert binary data to hexadecimal, just that, no fancy formatting and all. hexdump seems too clever, and it \"overformats\" for me. I want to take x

相关标签:
8条回答
  • 2020-12-13 06:15

    All the solutions seem to be hard to remember or too complex. I find using printf the shortest one:

    $ printf '%x\n' 256
    100
    

    But as noted in comments, this is not what author wants, so to be fair, below is the full answer.

    ... to use above to output actual binary data stream:

    printf '%x\n' $(cat /dev/urandom | head -c 5 | od -An -vtu1)
    

    What it does:

    • printf '%x\n' .... - prints a sequence of integers , i.e. printf '%x,' 1 2 3, will print 1,2,3,
    • $(...) - this is a way to get output of some shell command and process it
    • cat /dev/urandom - it outputs random binary data
    • head -c 5 - limits binary data to 5 bytes
    • od -An -vtu1 - octal dump command, converts binary to decimal

    As a testcase ('a' is 61 hex, 'p' is 70 hex, ...):

    $ printf '%x\n' $(echo "apple" | head -c 5 | od -An -vtu1)
    61
    70
    70
    6c
    65
    

    Or to test individual binary bytes, on input let’s give 61 decimal ('=' char) to produce binary data ('\\x%x' format does it). The above command will correctly output 3d (decimal 61):

    $printf '%x\n' $(echo -ne "$(printf '\\x%x' 61)" | head -c 5 | od -An -vtu1)
    3d
    
    0 讨论(0)
  • 2020-12-13 06:17

    Perhaps you could write your own small tool in C, and compile it on-the-fly:

    int main (void) {
      unsigned char data[1024];
      size_t numread, i;
    
      while ((numread = read(0, data, 1024)) > 0) {
        for (i = 0; i < numread; i++) {
          printf("%02x ", data[i]);
        }
      }
    
      return 0;
    }
    

    And then feed it from the standard input:

    cat /bin/ls | ./a.out
    

    You can even embed this small C program in a shell script using the heredoc syntax.

    0 讨论(0)
  • 2020-12-13 06:18

    With od (GNU systems):

    $ echo abc | od -A n -v -t x1 | tr -d ' \n'
    6162630a
    

    With hexdump (BSD systems):

    $ echo abc | hexdump -ve '/1 "%02x"'
    6162630a
    

    From Hex dump, od and hexdump:

    "Depending on your system type, either or both of these two utilities will be available--BSD systems deprecate od for hexdump, GNU systems the reverse."

    0 讨论(0)
  • 2020-12-13 06:19

    dd + hexdump will also work:

    dd bs=1 count=1 if=/dev/urandom 2>/dev/null  | hexdump -e '"%x"'
    
    0 讨论(0)
  • 2020-12-13 06:20

    If you need a large stream (no newlines) you can use tr and xxd (part of Vim) for byte-by-byte conversion.

    head -c1024 /dev/urandom | xxd -p | tr -d $'\n'
    

    Or you can use hexdump (POSIX) for word-by-word conversion.

    head -c1024 /dev/urandom | hexdump '-e"%x"'
    

    Note that the difference is endianness.

    0 讨论(0)
  • 2020-12-13 06:21

    Perhaps use xxd:

    % xxd -l 16 -p /dev/random
    193f6c54814f0576bc27d51ab39081dc
    
    0 讨论(0)
提交回复
热议问题