hexdump的C实现
将数据以16进制形式展现在很多时候非常有用,例如:
- 想知道结构体的内存布局以及字节对齐
- 想知道汉字用的什么编码方式
- 网络编程中追踪各个数据包的内容
- 查看不可见字符
hexdump是debug的强有力工具,以下是C语言实现。
void hexdump(const void *pdata, int len) {
int i, j, k, l;
const char *data = (const char*)pdata;
char buf[256], str[64], t[] = "0123456789ABCDEF";
for (i = j = k = 0; i < len; i++) {
if (0 == i % 16)
j += sprintf(buf + j, "%04xh: ", i);
buf[j++] = t[0x0f & (data[i] >> 4)];
buf[j++] = t[0x0f & data[i]];
buf[j++] = ' ';
str[k++] = isprint(data[i]) ? data[i] : '.';
if (0 == (i + 1) % 16) {
str[k] = 0;
j += sprintf(buf + j, "; %s\n", str);
printf("%s", buf);
j = k = buf[0] = str[0] = 0;
}
}
str[k] = 0;
if (k) {
for (l = 0; l < 3 * (16 - k); l++)
buf[j++] = ' ';
j += sprintf(buf + j, "; %s\n", str);
}
if (buf[0]) printf("%s", buf);
}
下面用hexdump工具来测试结构体字节对齐问题。
struct {
char a;
short b;
double c;
int d;
char e;
}x;
memset(&x, 0xcc, sizeof(x));
x.a = 'a';
x.b = 0x1234;
x.c = 3.14159;
x.d = 0x12345678;
x.e = 'e';
hexdump(&x, sizeof(x));
运行结果如下:
0000h: 61 CC 34 12 CC CC CC CC 6E 86 1B F0 F9 21 09 40 ; a.4.....n....!.@
0010h: 78 56 34 12 65 CC CC CC ; xV4.e...
可通过pragma修改字节对齐方式,例如使用1字节对齐。
#pragma pack(1)
struct {
char a;
short b;
double c;
int d;
char e;
}x;
#pragma pack()
执行同样的代码,结果如下:
0000h: 61 34 12 6E 86 1B F0 F9 21 09 40 78 56 34 12 65 ; a4.n....!.@xV4.e