How to create a hex dump from binary data in C++

http://stahlworks.com/dev/index.php?tool=csc01

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 <stdio.h>

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 <stdio.h>
#include <ctype.h>

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 <stdio.h>
#include <ctype.h>

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 <stdio.h>
#include <ctype.h>

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]

posted on 2013-04-15 18:36  androidme  阅读(472)  评论(0编辑  收藏  举报

导航