打印文件的二进制表示(Print binary representation of file)

2019-10-18 15:32发布

我需要将打印出类似UNIX中的XXD程序读取文件的二进制表示的功能,但我想我自己。 十六进制的作品只是%×罚款,但没有内置的格式的二进制文件。 有人知道怎么做吗?

Answer 1:

我通常不相信在回答这些各种各样的与完整的代码实现的问题,但是我是很多年前流传的代码这一点,我觉得有义务把它传递。 我已删除了所有的意见除了使用,所以你可以尝试找出它是如何工作的自己。

代码库16

#include <stdio.h>
#include <ctype.h>

// Takes a pointer to an arbitrary chunk of data and prints the first-len bytes.
void dump (void* data, unsigned int len)
{
  printf ("Size:  %d\n", len);

  if (len > 0) {
    unsigned width = 16;
    char *str = (char *)data;
    unsigned int j, i = 0;

    while (i < len) {
      printf (" ");

      for (j = 0; j < width; j++) {
        if (i + j < len)
          printf ("%02x ", (unsigned char) str [j]);
        else
          printf ("   ");

        if ((j + 1) % (width / 2) == 0)
          printf (" -  ");
      }

      for (j = 0; j < width; j++) {
        if (i + j < len)
          printf ("%c", isprint (str [j]) ? str [j] : '.');
        else
          printf (" ");
       }

       str += width;
       i += j;

      printf ("\n");
    }
  }
}


输出基底16(摘录自一个flash视频的前512个字节*)

Size:  512
 00 00 00 20 66 74 79 70  -  69 73 6f 6d 00 00 02 00  -  ... ftypisom....
 69 73 6f 6d 69 73 6f 32  -  61 76 63 31 6d 70 34 31  -  isomiso2avc1mp41
 00 06 e8 e6 6d 6f 6f 76  -  00 00 00 6c 6d 76 68 64  -  ....moov...lmvhd
 00 00 00 00 7c 25 b0 80  -  7c 25 b0 80 00 00 03 e8  -  ....|%..|%......
 00 0c d6 2a 00 01 00 00  -  01 00 00 00 00 00 00 00  -  ...*............
 00 00 00 00 00 01 00 00  -  00 00 00 00 00 00 00 00  -  ................
 00 00 00 00 00 01 00 00  -  00 00 00 00 00 00 00 00  -  ................
 00 00 00 00 40 00 00 00  -  00 00 00 00 00 00 00 00  -  ....@...........
 00 00 00 00 00 00 00 00  -  00 00 00 00 00 00 00 00  -  ................
 00 01 00 02 00 01 9f 38  -  74 72 61 6b 00 00 00 5c  -  .......8trak...\


我假设你已经知道如何分辨一个文件的大小和读取二进制模式文件,所以我会离开了这一点的讨论。 根据您的终端宽度,你可能需要调整的变量: width -代码当前专为80个字符终端。

我还假定当你提到xxd结合“二进制”你的意思,而不是基础2.如果要基座2,设置非文本width 〜6和取代printf ("%02x ", (unsigned char) str [j]); 有了这个:

{
  for (int k = 7; k >= 0; k--)
    printf ("%d", ((unsigned char)str [j] >> k) & 1);
  printf (" ");
}

所需要的变化是非常简单,你只需要你的八位字节的所有8位分别移位和屏蔽掉所有,但最低显著位。 记得做这似乎与直觉相反,在第一个订单,因为我们打印左到右。

输出基底2(摘录自一个flash视频的前512个字节*)

Size:  512
 00000000 00000000 00000000  -  00100000 01100110 01110100  -  ... ft
 01111001 01110000 01101001  -  01110011 01101111 01101101  -  ypisom
 00000000 00000000 00000010  -  00000000 01101001 01110011  -  ....is
 01101111 01101101 01101001  -  01110011 01101111 00110010  -  omiso2
 01100001 01110110 01100011  -  00110001 01101101 01110000  -  avc1mp
 00110100 00110001 00000000  -  00000110 11101000 11100110  -  41....
 01101101 01101111 01101111  -  01110110 00000000 00000000  -  moov..
 00000000 01101100 01101101  -  01110110 01101000 01100100  -  .lmvhd
 00000000 00000000 00000000  -  00000000 01111100 00100101  -  ....|%
 10110000 10000000 01111100  -  00100101 10110000 10000000  -  ..|%..
 00000000 00000000 00000011  -  11101000 00000000 00001100  -  ......

*为了简单起见,我们假装一个字节始终是8位。



Answer 2:

根据不同的语言,假设你有位运算,它可以让你的行为对一个变量的每一位,你可以做到以下几点。 文件读入到一个缓冲液,或线,如果需要的编码,它强制扩展的ASCII(8位/ 1字节字符)现在,当你得到缓冲,从7循环到0,并使用和按位和一个转移到检查每一个位值,让我给C的一个例子:

// gcc -Wall -Wextra -std=c99 xxd.c
#include <stdio.h>
#include <string.h>

int main() {
  // Whatever buffer size you chose.
  char buffer[32];
  //Feel free to replace stdin to a File Pointer, or any other stream
  // Reading into a char, means reading each byte at once
  while (!feof(stdin)) {
    // Read at most buffer bytes. Since its ASCII 1 byte = 1 char.
    fgets(buffer, sizeof(buffer), stdin);
    // Iterate though each character in the string/buffer.
    const size_t len = strlen(buffer);
    for (size_t j = 0; j < len; j++) {
      // Print the most significant bit first.
      for (int i = 7; i >=0; i--) {
        // Check if the i-th bit is set
        printf(buffer[j] & (1 << i) ? "1" : "0");
      }
    }
  }

  return 0;
}


文章来源: Print binary representation of file