Skip to content

Instantly share code, notes, and snippets.

@tatsuhiro-t
Last active August 29, 2015 14:21
Show Gist options
  • Save tatsuhiro-t/6c0168fa48bd9056cdd4 to your computer and use it in GitHub Desktop.
Save tatsuhiro-t/6c0168fa48bd9056cdd4 to your computer and use it in GitHub Desktop.
hexdump -C compatible output; useful for debugging
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#define HEXDUMP_MIN(X, Y) ((X) < (Y) ? (X) : (Y))
static void hexdump8(FILE *out, const uint8_t *first, const uint8_t *last) {
const uint8_t *stop = HEXDUMP_MIN(first + 8, last);
const uint8_t *k;
for(k = first; k != stop; ++k) {
fprintf(out, "%02x ", *k);
}
// each byte needs 3 spaces (2 hex value and space)
for(; stop != first + 8; ++stop) {
fputs(" ", out);
}
// we have extra space after 8 bytes
fputc(' ', out);
}
static void hexdump(FILE *out, const uint8_t *src, size_t len) {
size_t buflen = 0;
int repeated = 0;
uint8_t buf[16];
const uint8_t *end, *i;
if(len == 0) {
return;
}
end = src + len;
i = src;
for(;;) {
const uint8_t *stop;
uint8_t *p;
size_t nextlen = HEXDUMP_MIN(16, end - i);
if(nextlen == buflen && memcmp(buf, i, buflen) == 0) {
// as long as adjacent 16 bytes block are the same, we just
// print single '*'.
if(!repeated) {
repeated = 1;
fputs("*\n", out);
}
i += nextlen;
continue;
}
repeated = 0;
fprintf(out, "%08lx", i - src);
if(i == end) {
fputc('\n', out);
break;
}
fputs(" ", out);
hexdump8(out, i, end);
hexdump8(out, i + 8, i + 8 < end ? end : i + 8);
fputc('|', out);
stop = HEXDUMP_MIN(i + 16, end);
buflen = stop - i;
p = buf;
for(; i != stop; ++i) {
*p++ = *i;
if(0x20 <= *i && *i <= 0x7e) {
fputc(*i, out);
}
else {
fputc('.', out);
}
}
fputs("|\n", out);
}
}
int main() {
const uint8_t b[] = "hello\x00world\r\n";
hexdump(stderr, b, sizeof(b));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment