• 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]
    
  • 相关阅读:
    (一)jQuery EasyUI 的EasyLoader载入原理
    java playframework
    android Handlerr.removeCallbacksAndMessages(null)的妙用
    云已成为一种趋势,大有可为
    将一个4X4的数组进行逆时针旋转90度后输出,要求原数组数据随机输入
    小强的HTML5移动开发之路(40)——jqMobi中实践header定义的几种方式
    AngularJS中的依赖注入
    极光消息推送服务器端开发实现推送(下)
    用CSS指定外部链接的样式
    版本控制(1)——SVN
  • 原文地址:https://www.cnblogs.com/androidme/p/3022626.html
Copyright © 2020-2023  润新知