【问题标题】:Show Hexadecimal Numbers Of a File显示文件的十六进制数字
【发布时间】:2011-01-01 12:10:03
【问题描述】:

我想构建一个 bash 程序,它可以读取文件,如 *.bin 并打印其所有十六进制数字,就像 'hex' 编辑器所做的那样。我可以从哪里开始?

【问题讨论】:

标签: bash file-io hex


【解决方案1】:

使用od命令,

od -t x1 文件名

【讨论】:

  • od 是 Linux 程序还是 bash 函数?对不起,我是一个真正的初学者。
  • @Nathan Campos:您可以使用which od 查找,如果您获得程序的名称,则它是一个外部程序(对于od,它可能是)。
  • 在 unix 中非常标准,从一开始就存在。
  • @GregHewgill 错了。从我的 Ubuntu 机器上看这个。 ~ $ type [ [ 是一个内置的 shell ~ $ which [ /usr/bin/[
  • @NathanCampos 更重要的是,它是 POSIX:pubs.opengroup.org/onlinepubs/9699919799/utilities/od.html :-)
【解决方案2】:

你可以使用 od. "od -x file" 为什么要重新发明那个轮子?

【讨论】:

    【解决方案3】:

    如果你有 hexdump,你也可以使用它

    hexdump -x /usr/bin/binaryfile
    

    【讨论】:

      【解决方案4】:

      编辑:添加了“字节流”功能。如果脚本名称包含单词“stream”(例如,它是一个符号链接,例如ln -s bash-hexdump bash-hexdump-stream 并以./bash-hexdump-stream 运行),它将输出表示文件内容的连续十六进制字符流。否则它的输出将类似于hexdump -C

      由于 Bash 并不擅长二进制,因此需要很多技巧:

      #!/bin/bash
      # bash-hexdump
      # by Dennis Williamson - 2010-01-04
      # in response to http://stackoverflow.com/questions/2003803/show-hexadecimal-numbers-of-a-file
      # usage: bash-hexdump file
      
      if [[ -z "$1" ]]
      then
          exec 3<&0                           # read stdin
          [[ -p /dev/stdin ]] || tty="yes"    # no pipe
      else
          exec 3<"$1"            # read file
      fi
      
      # if the script name contains "stream" then output will be continuous hex digits
      # like hexdump -ve '1/1 "%.2x"'
      [[ $0 =~ stream ]] && nostream=false || nostream=true
      
      saveIFS="$IFS"
      IFS=""                     # disables interpretation of \t, \n and space
      saveLANG="$LANG"
      LANG=C                     # allows characters > 0x7F
      bytecount=0
      valcount=0
      $nostream && printf "%08x  " $bytecount
      while read -s -u 3 -d '' -r -n 1 char    # -d '' allows newlines, -r allows \
      do
          ((bytecount++))
          printf -v val "%02x" "'$char"    # see below for the ' trick
          [[ "$tty" == "yes" && "$val" == "04" ]] && break    # exit on ^D
          echo -n "$val"
          $nostream && echo -n " "
          ((valcount++))
          if [[ "$val" < 20 || "$val" > 7e ]]
          then
              string+="."                  # show unprintable characters as a dot
          else
              string+=$char
          fi
          if $nostream && (( bytecount % 8 == 0 ))      # add a space down the middle
          then
              echo -n " "
          fi
          if (( bytecount % 16 == 0 ))   # print 16 values per line
          then
              $nostream && echo "|$string|"
              string=''
              valcount=0
              $nostream && printf "%08x  " $bytecount
          fi
      done
      
      if [[ "$string" != "" ]]            # if the last line wasn't full, pad it out
      then
          length=${#string}
          if (( length > 7 ))
          then
              ((length--))
          fi
          (( length += (16 - valcount) * 3 + 4))
          $nostream && printf "%${length}s\n" "|$string|"
          $nostream && printf "%08x  " $bytecount
      fi
      $nostream && echo
      
      LANG="$saveLANG";
      IFS="$saveIFS"
      

      撇号技巧记录在here。相关部分说:

      如果前导字符是 单引号或双引号, 值应为数值 的底层代码集 单引号后的字符 或双引号。

      以下是脚本的一些输出,显示了我的/bin/bash 的前几行以及更多内容:

      00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| 00000010 02 00 03 00 01 00 00 00 e0 1e 06 08 34 00 00 00 |............4......| 00000020 c4 57 0d 00 00 00 00 00 34 00 20 00 09 00 28 00 |.W......4. ...(。| 00000030 1d 00 1c 00 06 00 00 00 34 00 00 00 34 80 04 08 |............4......4......| . . . 00000150 01 00 00 00 2f 6c 69 62 2f 6c 64 2d 6c 69 6e 75 |..../lib/ld-linu| 00000160 78 2e 73 6f 2e 32 00 00 04 00 00 00 10 00 00 00 |x.so.2........| 00000170 01 00 00 00 47 4e 55 00 00 00 00 00 02 00 00 00 |....GNU.........|

      【讨论】:

      • 顺便说一下,这个脚本的输出格式和hexdump -C或者hd一样。
      • 很高兴看到有人用 bash 做不寻常的甚至是二进制的事情。非常有趣的一段代码!
      • @nkvnkv:阅读问题:“我想构建一个 bash 程序......”另外,请注意我的答案已被 OP 接受并阅读我的答案所附的 cmets。感谢您的反对。
      猜你喜欢
      • 2014-12-20
      • 2014-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-21
      • 2016-06-28
      • 2014-05-24
      相关资源
      最近更新 更多