Skip to content

Instantly share code, notes, and snippets.

@dotkt
Forked from mcnewton/example.out
Created May 11, 2019 15:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dotkt/c25b36412fc61c60028fc0d55d48f8fc to your computer and use it in GitHub Desktop.
Save dotkt/c25b36412fc61c60028fc0d55d48f8fc to your computer and use it in GitHub Desktop.
hex dump C buffer
#include <stdio.h>
#include <string.h>
#include <assert.h>
int hexdump(FILE *fd, void const *ptr, size_t length, int linelen, int split);
int main(void)
{
FILE *fd;
char buffer[100] = "0123456789ABCDEFabcdef0123456789AAAABBBBCCCCDDDDHello World\rTest-line\n";
hexdump(stdout, buffer, strlen(buffer), 16, 8);
return 0;
}
/*
* hexdump - output a hex dump of a buffer
*
* fd is file descriptor to write to
* data is pointer to the buffer
* length is length of buffer to write
* linelen is number of chars to output per line
* split is number of chars in each chunk on a line
*/
int hexdump(FILE *fd, void const *data, size_t length, int linelen, int split)
{
char buffer[512];
char *ptr;
const void *inptr;
int pos;
int remaining = length;
inptr = data;
/*
* Assert that the buffer is large enough. This should pretty much
* always be the case...
*
* hex/ascii gap (2 chars) + closing \0 (1 char)
* split = 4 chars (2 each for hex/ascii) * number of splits
*
* (hex = 3 chars, ascii = 1 char) * linelen number of chars
*/
assert(sizeof(buffer) >= (3 + (4 * (linelen / split)) + (linelen * 4)));
/*
* Loop through each line remaining
*/
while (remaining > 0) {
int lrem;
int splitcount;
ptr = buffer;
/*
* Loop through the hex chars of this line
*/
lrem = remaining;
splitcount = 0;
for (pos = 0; pos < linelen; pos++) {
/* Split hex section if required */
if (split == splitcount++) {
sprintf(ptr, " ");
ptr += 2;
splitcount = 1;
}
/* If still remaining chars, output, else leave a space */
if (lrem) {
sprintf(ptr, "%0.2x ", *((unsigned char *) inptr + pos));
lrem--;
} else {
sprintf(ptr, " ");
}
ptr += 3;
}
*ptr++ = ' ';
*ptr++ = ' ';
/*
* Loop through the ASCII chars of this line
*/
lrem = remaining;
splitcount = 0;
for (pos = 0; pos < linelen; pos++) {
unsigned char c;
/* Split ASCII section if required */
if (split == splitcount++) {
sprintf(ptr, " ");
ptr += 2;
splitcount = 1;
}
if (lrem) {
c = *((unsigned char *) inptr + pos);
if (c > 31 && c < 127) {
sprintf(ptr, "%c", c);
} else {
sprintf(ptr, ".");
}
lrem--;
/*
* These two lines would pad out the last line with spaces
* which seems a bit pointless generally.
*/
/*
} else {
sprintf(ptr, " ");
*/
}
ptr++;
}
*ptr = '\0';
fprintf(fd, "%s\n", buffer);
inptr += linelen;
remaining -= linelen;
}
return 0;
}
example with linelen=16, split=8
30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 46 01234567 89ABCDEF
61 62 63 64 65 66 30 31 32 33 34 35 36 37 38 39 abcdef01 23456789
41 41 41 41 42 42 42 42 43 43 43 43 44 44 44 44 AAAABBBB CCCCDDDD
48 65 6c 6c 6f 20 57 6f 72 6c 64 0d 54 65 73 74 Hello Wo rld.Test
2d 6c 69 6e 65 0a -line.
example with linelen=16, split=4
30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 46 0123 4567 89AB CDEF
61 62 63 64 65 66 30 31 32 33 34 35 36 37 38 39 abcd ef01 2345 6789
41 41 41 41 42 42 42 42 43 43 43 43 44 44 44 44 AAAA BBBB CCCC DDDD
48 65 6c 6c 6f 20 57 6f 72 6c 64 0d 54 65 73 74 Hell o Wo rld. Test
2d 6c 69 6e 65 0a -lin e.
example with linelen=16, split=7, though linelen should really be a multiple of split
30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 46 0123456 789ABCD EF
61 62 63 64 65 66 30 31 32 33 34 35 36 37 38 39 abcdef0 1234567 89
41 41 41 41 42 42 42 42 43 43 43 43 44 44 44 44 AAAABBB BCCCCDD DD
48 65 6c 6c 6f 20 57 6f 72 6c 64 0d 54 65 73 74 Hello W orld.Te st
2d 6c 69 6e 65 0a -line.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment