0

I confused how to convert const char * to base64 with 2 Questions:
Question #1 how do I defined the length of output string that would perfectly match the length of output base64?I have found a code which from apple opensource,the code in below http://www.opensource.apple.com/source/QuickTimeStreamingServer/QuickTimeStreamingServer-452/CommonUtilitiesLib/base64.c
or I could directly use "atlenc.h" in VC++.if the length of coded_dst which I have defined is smaller than the actually,the program may crashed

int Base64encode(char *coded_dst, const char *plain_src, int len_plain_src)
{

    const char basis_64[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    int i;
    char *p;

    p = coded_dst;
    for (i = 0; i < len_plain_src - 2; i += 3) {
    *p++ = basis_64[(plain_src[i] >> 2) & 0x3F];
    *p++ = basis_64[((plain_src[i] & 0x3) << 4) |
                ((int) (plain_src[i + 1] & 0xF0) >> 4)];
     *p++ = basis_64[((plain_src[i + 1] & 0xF) << 2) |
                ((int) (plain_src[i + 2] & 0xC0) >> 6)];
     *p++ = basis_64[plain_src[i + 2] & 0x3F];
     }
     if (i < len_plain_src) {
      *p++ = basis_64[(plain_src[i] >> 2) & 0x3F];
      if (i == (len_plain_src - 1)) {
       *p++ = basis_64[((plain_src[i] & 0x3) << 4)];
       *p++ = '=';
    }
   else {
       *p++ = basis_64[((plain_src[i] & 0x3) << 4) |
                    ((int) (plain_src[i + 1] & 0xF0) >> 4)];
       *p++ = basis_64[((plain_src[i + 1] & 0xF) << 2)];
    }
    *p++ = '=';
    }

     *p++ = '\0';
   return p - coded_dst;
  }

Question #2 as we all well know that the type of byte in C++ is unsigned char,how do I convert the char * to unsigned char *? thanks regards Ken

B001ᛦ
  • 2,036
  • 6
  • 23
  • 31
Ken Yup
  • 35
  • 6

1 Answers1

0

The design of your function, based on the signature, tells me it's up to the caller to provide a sufficient buffer for output. This would be unsafe in your example because the caller isn't informing the function how large that buffer is. Your function has no chance to limit output to coded_dst to the buffer provided, so you should add, at the least, a parameter for that.

As such, you would need to check as you loop to be sure p, a pointer into coded_dst, stays within that limit, returning an error to the caller if there's insufficient room.

That said, notice how many increments of p occur for every 3 source items processed. The ratio is 3/4...for every 3 that go into that loop, 4 come out. So, to start the calculation of the required length, begin with

 ( len_plain_src / 3 ) * 4;

Now, consider r = len_plain_src % 3; If r is zero, your algorithm adds 2 more bytes. If r has a remainder, your algorithm adds 3 more bytes.

After that, you append a zero terminator.

Look carefully, I've not clearly analyzed this, but you may have an error in the closing '=' appended at the tail for the case where (i<len_plain_src) - you may have added two of them instead of just one.

Now, to handle the unsigned char, you could change the declaration and initial assignment of p with,

unsigned char * p = (unsigned char *) coded_dst;

At which point it would be more convenient for you if you declare basis_64 to be unsigned char

JVene
  • 1,611
  • 10
  • 10