我通常不相信用完整的代码实现来回答这类问题,但是很多年前我收到了这段代码,我觉得有义务把它传递下去。除了用法之外,我已经删除了所有的 cmets,所以你可以自己尝试弄清楚它是如何工作的。
代码 base 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");
}
}
}
输出 base 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 位并屏蔽除最不重要的位之外的所有位。请记住以一开始似乎违反直觉的顺序执行此操作,因为我们从左到右打印。
输出 base 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位。