How to create a hex dump from binary data in C++ with a few lines of code: free source code examples for instant use in any project, for windows and linux.
starting point: let's say we have a simple program like this:
#include
int main(int argc, char *argv[])
{
char abStack[100];
printf("hello world, abStack == %p\n", abStack);
}
and we want to see the binary contents of abStack in a well-formatted hex dump.
solution 1: triple-column hex dump with ASCII representation
#include
#include
void hexdump(void *pAddressIn, long lSize)
{
char szBuf[100];
long lIndent = 1;
long lOutLen, lIndex, lIndex2, lOutLen2;
long lRelPos;
struct { char *pData; unsigned long lSize; } buf;
unsigned char *pTmp,ucTmp;
unsigned char *pAddress = (unsigned char *)pAddressIn;
buf.pData = (char *)pAddress;
buf.lSize = lSize;
while (buf.lSize > 0)
{
pTmp = (unsigned char *)buf.pData;
lOutLen = (int)buf.lSize;
if (lOutLen > 16)
lOutLen = 16;
// create a 64-character formatted output line:
sprintf(szBuf, " > "
" "
" %08lX", pTmp-pAddress);
lOutLen2 = lOutLen;
for(lIndex = 1+lIndent, lIndex2 = 53-15+lIndent, lRelPos = 0;
lOutLen2;
lOutLen2--, lIndex += 2, lIndex2++
)
{
ucTmp = *pTmp++;
sprintf(szBuf + lIndex, "%02X ", (unsigned short)ucTmp);
if(!isprint(ucTmp)) ucTmp = '.'; // nonprintable char
szBuf[lIndex2] = ucTmp;
if (!(++lRelPos & 3)) // extra blank after 4 bytes
{ lIndex++; szBuf[lIndex+2] = ' '; }
}
if (!(lRelPos & 3)) lIndex--;
szBuf[lIndex ] = '<';
szBuf[lIndex+1] = ' ';
printf("%s\n", szBuf);
buf.pData += lOutLen;
buf.lSize -= lOutLen;
}
}
int main(int argc, char *argv[])
{
char abStack[100];
printf("hello world, dump of abStack follows:\n");
hexdump(abStack, 100);
}
example output:
hello world, dump of abStack follows:
>08080000 00000000 00003200 88000000< ..........2..... 00000000
>08080000 781B3200 00003200 8CFC1200< ....x.2...2..... 00000010
>90FC1200 B0FF1200 F088F977 94BEF477< ...........w...w 00000020
>9161E577 D0FE1200 B8FE1200 999E3600< .a.w..........6. 00000030
>00000000 E0FE1200 1B504000 D0FE1200< .........P@..... 00000040
>04904000 27B243B6 03000000 A6D26C36< ..@.'.C.......l6 00000050
>CA00C701< .... 00000060
the above hexdump() function provides
- the raw binary data as hex values, in groups of 4 bytes, with 16 bytes per line
- an ascii representation of the data, where printable
- the hex offset of each record (line)
if you don't want the output on terminal but, for example, into a file-based tracing system like mtk, simply change the printf statement within hexdump().
the above example dumps only 16 data bytes per record. if you need
something more compact, try this:
solution 2: hex dump with 32 data bytes, 85 chars per output line
#include
#include
void hexdump(void *pAddressIn, long lSize)
{
char szBuf[100];
long lIndent = 1;
long lOutLen, lIndex, lIndex2, lOutLen2;
long lRelPos;
struct { char *pData; unsigned long lSize; } buf;
unsigned char *pTmp,ucTmp;
unsigned char *pAddress = (unsigned char *)pAddressIn;
buf.pData = (char *)pAddress;
buf.lSize = lSize;
while (buf.lSize > 0)
{
pTmp = (unsigned char *)buf.pData;
lOutLen = (int)buf.lSize;
if (lOutLen > 32)
lOutLen = 32;
// create a 85-character formatted output line:
sprintf(szBuf, " "
" "
" [%08lX]", pTmp-pAddress);
lOutLen2 = lOutLen;
for(lIndex = lIndent, lRelPos = 0;
lOutLen2;
lOutLen2--, lIndex += 2
)
{
ucTmp = *pTmp++;
sprintf(szBuf + lIndex, "%02X ", (unsigned short)ucTmp);
if (!(++lRelPos & 3)) // extra blank after 4 bytes
lIndex++;
}
if (!(lRelPos & 3)) lIndex--;
szBuf[lIndex+1] = ' ';
printf("%s\n", szBuf);
buf.pData += lOutLen;
buf.lSize -= lOutLen;
}
}
int main(int argc, char *argv[])
{
char abStack[100];
printf("hello world, dump of abStack follows:\n");
hexdump(abStack, 100);
}
example output follows (some bytes in the middle have been replaced by "(...)"):
hello world, dump of abStack follows:
08080000 00000000 00003200 (...) 781B3200 00003200 8CFC1200 [00000000]
90FC1200 B0FF1200 F088F977 (...) D0FE1200 B8FE1200 999E3600 [00000020]
00000000 E0FE1200 5B4D4000 (...) 852A9A06 05000000 8C3F15E2 [00000040]
CD00C701 (...) [00000060]
the most compact solution uses only 76 characters per output line:
solution 3: hex dump with 32 data bytes, 76 chars per output line
#include
#include
void hexdump(void *pAddressIn, long lSize)
{
char szBuf[100];
long lIndent = 0;
long lOutLen, lIndex, lIndex2, lOutLen2;
long lRelPos;
struct { char *pData; unsigned long lSize; } buf;
unsigned char *pTmp,ucTmp;
unsigned char *pAddress = (unsigned char *)pAddressIn;
buf.pData = (char *)pAddress;
buf.lSize = lSize;
while (buf.lSize > 0)
{
pTmp = (unsigned char *)buf.pData;
lOutLen = (int)buf.lSize;
if (lOutLen > 32)
lOutLen = 32;
// create a 76-character formatted output line:
sprintf(szBuf, " "
" "
" [%08lX]", pTmp-pAddress);
lOutLen2 = lOutLen;
for(lIndex = lIndent, lRelPos = 0;
lOutLen2;
lOutLen2--, lIndex += 2
)
{
ucTmp = *pTmp++;
sprintf(szBuf + lIndex, "%02X ", (unsigned short)ucTmp);
}
szBuf[lIndex+1] = ' ';
printf("%s\n", szBuf);
buf.pData += lOutLen;
buf.lSize -= lOutLen;
}
}
int main(int argc, char *argv[])
{
char abStack[100];
printf("hello world, dump of abStack follows:\n");
hexdump(abStack, 100);
}
example output follows (some bytes in the middle have been replaced by "(...)"):
080800000000000000003200 (...) 781B3200000032008CFC1200 [00000000]
90FC1200B0FF1200F088F977 (...) D0FE1200B8FE1200999E3600 [00000020]
00000000E0FE12002B4D4000 (...) AE6E71210500000054B6122D [00000040]
CE00C701 (...) [00000060]
|