用C ++编写Base64图像文件

时间:2018-03-28 18:08:40

标签: c++ image encoding base64

我正在编写一些简单的代码来将文件编码为base64。我有一个简短的c ++代码,它将文件读入矢量并将其转换为unsigned char *。我这样做,所以我可以正确使用我得到的编码功能。

问题:它适用于文本文件(不同大小),但它不能处理图像文件。我无法弄清楚原因。是什么给了什么?

对于包含文字text.txt的简单abcd,我的代码和bash $( base64 text.txt )的输出都是相同的。

另一方面,当我输入图像时,输出类似于iVBORwOKGgoAAAAAAA......AAA==,或者有时以corrupted size vs prev_size Aborted (core dumped)结束,前几个字节是正确的。

代码:

static std::vector<char> readBytes(char const* filename)
{
    std::ifstream ifs(filename, std::ios::binary|std::ios::ate);
    std::ifstream::pos_type pos = ifs.tellg();
    std::vector<char> result(pos);
    ifs.seekg(0, std::ios::beg);
    ifs.read(&result[0], pos);

    return result;
}

static char Base64Digits[] =
 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

int ToBase64Simple( const BYTE* pSrc, int nLenSrc, char* pDst, int nLenDst )
{
   int nLenOut= 0;
   while ( nLenSrc > 0 ) {

      if (nLenOut+4 > nLenDst) {
      cout << "error\n";
      return(0); // error
      }

      // read three source bytes (24 bits)
      BYTE s1= pSrc[0];   // (but avoid reading past the end)
      BYTE s2= 0; if (nLenSrc>1) s2=pSrc[1]; //------ corrected, thanks to  jprichey
      BYTE s3= 0; if (nLenSrc>2) s3=pSrc[2];

      DWORD n;
      n =  s1;    // xxx1
      n <<= 8;    // xx1x
      n |= s2;    // xx12
      n <<= 8;    // x12x
      n |= s3;    // x123

      //-------------- get four 6-bit values for lookups
      BYTE m4= n & 0x3f;  n >>= 6;
      BYTE m3= n & 0x3f;  n >>= 6;
      BYTE m2= n & 0x3f;  n >>= 6;
      BYTE m1= n & 0x3f;

      //------------------ lookup the right digits for output
      BYTE b1 = Base64Digits[m1];
      BYTE b2 = Base64Digits[m2];
      BYTE b3 = Base64Digits[m3];
      BYTE b4 = Base64Digits[m4];

      //--------- end of input handling
      *pDst++ = b1;
      *pDst++ = b2;
      if ( nLenSrc >= 3 ) {  // 24 src bits left to encode, output xxxx
         *pDst++ = b3;
         *pDst++ = b4;
      }
      if ( nLenSrc == 2 ) {  // 16 src bits left to encode, output xxx=
         *pDst++ = b3;
         *pDst++ = '=';
         }
      if ( nLenSrc == 1 ) {  // 8 src bits left to encode, output xx==
         *pDst++ = '=';
         *pDst++ = '=';
      }
      pSrc    += 3;
      nLenSrc -= 3;
      nLenOut += 4;
   }
   // Could optionally append a NULL byte like so:
   *pDst++= 0; nLenOut++;
   return( nLenOut );
}

int main(int argc, char* argv[])
{
    std::vector<char> mymsg;
    mymsg = readBytes(argv[1]);
    char* arr = &mymsg[0];
    int len = mymsg.size();
    int lendst = ((len+2)/3)*4;
    unsigned char* uarr = (unsigned char *) malloc(len*sizeof(unsigned char));
    char* dst = (char *) malloc(lendst*sizeof(char));;
    mymsg.clear(); //free()

    // convert to unsigned char
    strncpy((char*)uarr, arr, len);

    int lenOut = ToBase64Simple(uarr, len, dst, lendst);
    free(uarr);

    int cont = 0;
    while (cont < lenOut) //(dst[cont] != 0)
        cout << dst[cont++];
    cout << "\n";
}

欢迎任何见解。

1 个答案:

答案 0 :(得分:1)

我看到两个问题。

首先,您在使用它之前清除了mymsg向量。这使arr指针悬空(指向不再分配的内存)。当您访问arr以获取数据时,您最终会得到未定义的行为。

然后使用strncpy复制(可能)二进制数据。当该文件到达文件中的第一个nul(0)字节时,该副本将停止,因此不会复制所有数据。您应该使用memcpy代替。