晴耕雨読

working in the fields on fine days and reading books on rainy days

[C言語] 16進数ダンプ (Hexdump) 関数の作り方

C言語でバイト列を扱うときに16進数ダンプ (Hexdump) するための関数を作る方法について説明します。 以下のプログラムは、バイト列の中身を16進数表示+印字可能な文字であれば印字するための関数 hexdump を実装して使う例です。 /dev/urandom から擬似乱数文字列を生成し、その結果を hexdump で出力させています。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

void hexdump(const void* data, size_t size) 
{
    char ascii[17];
    size_t i, j;
    ascii[16] = '\0';
    for (i = 0; i < size; ++i) {
        printf("%02X ", ((unsigned char*)data)[i]);
        if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') {
            ascii[i % 16] = ((unsigned char*)data)[i];
        } else {
            ascii[i % 16] = '.';
        }
        if ((i+1) % 8 == 0 || i+1 == size) {
            printf(" ");
            if ((i+1) % 16 == 0) {
                printf("|  %s \n", ascii);
            } else if (i+1 == size) {
                ascii[(i+1) % 16] = '\0';
                if ((i+1) % 16 <= 8) {
                    printf(" ");
                }
                for (j = (i+1) % 16; j < 16; ++j) {
                    printf("   ");
                }
                printf("|  %s \n", ascii);
            }
        }
    }
}

int main()
{
    int fd = open("/dev/urandom", O_RDONLY);
    if (fd == -1) {  // ファイルオープン失敗時
        abort();
    }
    size_t wanted_len = 256;
    char buf[256];
    ssize_t len = read(fd, buf, wanted_len);
    if (len != wanted_len) {  // バリデーションチェック
        abort();
    }
    close(fd);
    hexdump(buf, wanted_len);  // 16進数ダンプ
}

hexdumpの結果は以下のようになります。

11 B7 FC F8 F1 98 2B B1  EC C4 35 C1 6D 05 32 E7  |  ......+...5.m.2. 
F0 17 40 0B 36 44 76 3D  B0 AC 2A A9 70 E2 46 8D  |  ..@.6Dv=..*.p.F. 
82 9F 86 B8 46 2E 67 EE  69 EE A5 3B B0 80 06 AB  |  ....F.g.i..;.... 
72 2D 00 98 4F 46 F2 4A  16 51 A1 31 33 EF CB CB  |  r-..OF.J.Q.13... 
88 3D 03 1E A4 00 B3 33  8E 2D 2B 01 A4 89 94 12  |  .=.....3.-+..... 
55 7E 48 0A 4D 1F 86 83  86 30 8C D7 09 46 10 71  |  U~H.M....0...F.q 
E2 80 E7 87 E5 BA C6 03  9A CB F6 83 04 B8 A2 03  |  ................ 
6A FC 08 D7 C7 D9 6A 41  70 0C C5 3E CE FF 00 1A  |  j.....jAp..>.... 
ED EF B2 FA DA 07 C3 DD  DC 1C 4D 10 86 E2 80 07  |  ..........M..... 
B2 7B 44 7E 81 A1 FC 36  D6 B6 71 09 9B 92 6E A0  |  .{D~...6..q...n. 
40 9E CB 93 17 84 AD AF  3E FE 89 F6 16 B1 14 FF  |  @.......>....... 
3B 6B 9F 3B 3E 8F FF 3E  DC 5D 35 BB BD 1B AC 74  |  ;k.;>..>.]5....t 
BE 0B 9A 74 D3 AD 49 D9  E4 4F 3F 4F 47 1C D9 E6  |  ...t..I..O?OG... 
D1 8B C1 69 26 88 E5 F9  D9 35 6B C7 4D CA 0D BF  |  ...i&....5k.M... 
AE 8D 66 E5 CA 18 B4 C7  84 4C 3C D2 90 72 CD 06  |  ..f......L<..r.. 
E7 B1 4A BE BF 27 59 E4  3B 05 09 53 D8 8E 1D 4A  |  ..J..'Y.;..S...J

以上です。

参考資料