BASE64图像文件用C 编码

Base64 image file encoding with C++

本文关键字:编码 文件 图像 BASE64      更新时间:2023-10-16

我正在编写一些简单的代码将文件编码为base64。我有一个简短的C 代码,该代码将文件读为向量并将其转换为未签名的char*。我这样做,以便我可以正确使用我获得的编码功能。

问题:它可以与文本文件(不同尺寸(一起使用,但它无法与图像文件一起使用。我无法弄清楚原因。什么给?

对于包含文本abcd的简单text.txt,我的代码和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 << "errorn";
      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";
}

欢迎任何见解。

我看到了两个问题。

首先,在使用它之前,您要清除mymsg矢量。这会使arr指针悬挂(指向不再分配的内存(。当您访问arr以获取数据时,您最终会出现不确定的行为。

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