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]

你可能感兴趣的:(create)