2016년 6월 29일 수요일

hex dump

#include <stdio.h>
#include <inttypes.h>

inline char nibble(char n)
{
        return n + (n > 9 ? 'a' - 10 : '0');
}

static void dump(const void *data, unsigned len, const char *ind)
{
#define DUMPW  16
#define ZBASE (DUMPW * 3)

        if (!data) return;
        if (!ind) ind = "";

        char buf[DUMPW * 4 + 1];
        const int8_t *d = (const int8_t *)data;
        unsigned lines = (len + DUMPW - 1) / DUMPW;
        unsigned l, p, z;

        for (l = 0; l < lines; ++l) {
                for (p = z = 0; z < DUMPW; ++z) {
                        uint32_t c = *d++;
                        buf[ZBASE + z] = (0x20 <= c && c <= 0x7e) ? c : '.';
                        buf[p++] = nibble((c >> 4) & 0xF);
                        buf[p++] = nibble(c & 0xF);
                        buf[p++] = ' ';
                        if (--len == 0)
                                break;
                }
                //for (; p < ZBASE; ++p) buf[p] = ' ';
                memset(buf + p, ' ', ZBASE - p);
                buf[ZBASE + z + 1] = 0;
                printf("%s%s\n", ind, buf);
        }
}