Skip to content

Instantly share code, notes, and snippets.

@mcnewton
Last active November 14, 2023 19:25
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save mcnewton/14322391d50240ec9ebf to your computer and use it in GitHub Desktop.
Save mcnewton/14322391d50240ec9ebf to your computer and use it in GitHub Desktop.
hex dump C buffer
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.
/*
* Copyright 2015 Matthew Newton
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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;
}
@timlegge
Copy link

You don't have a licence mentioned. Is there one?

@mcnewton
Copy link
Author

Thanks for asking - added!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment