Link to home
Start Free TrialLog in
Avatar of urif
urif

asked on

base 64 encoding and decoding

i wrote two functions, one to decode base64 and one to decode it. but i'm going nowhere. i know there is a library around with base64.c or .h

any ideas?

or any ideas how can i implemente base64?

what i'm trying to do is base64Encode(string str)

thanks!
Avatar of yashik
yashik

What do you mean "going nowhere". Please be more specific
MIME base64 decoder/encoder (with source)
   ftp://ftp.dnttm.ro/pub/simtelnet/msdos/decode/mime64b.zip
Avatar of urif

ASKER

thanks, i just need a simple base64 function to encode or decode that's all, and in c++, i mean

int base64encode(string to encode)

int base64decode(string to decode)

the ftp link you put is inaccesible, and the two examples are writen in a c that my compiler won't understand.

thanks anyway
Avatar of urif

ASKER

this is the code i'm talking about, when compiling int with vc++ 6 it throwing an error:
"unexpected end of file while looking for precompiled header directive"

i don't know what else to check

this is base64.cpp
--------------start-----------------------------------
#include "Base64.h"


const char          fillchar = '=';

static string       cvt = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

string Base64::encode(string data)
{
    auto     string::size_type  i;
    auto     char               c;
    auto     string::size_type  len = data.length();
    auto     string             ret;

    for (i = 0; i < len; ++i)
    {
        c = (data[i] >> 2) & 0x3f;
        ret.append(1, cvt[c]);
        c = (data[i] << 4) & 0x3f;
        if (++i < len)
            c |= (data[i] >> 4) & 0x0f;

        ret.append(1, cvt[c]);
        if (i < len)
        {
            c = (data[i] << 2) & 0x3f;
            if (++i < len)
                c |= (data[i] >> 6) & 0x03;

            ret.append(1, cvt[c]);
        }
        else
        {
            ++i;
            ret.append(1, fillchar);
        }

        if (i < len)
        {
            c = data[i] & 0x3f;
            ret.append(1, cvt[c]);
        }
        else
        {
            ret.append(1, fillchar);
        }
    }

    return(ret);
}

string Base64::decode(string data)
{
    auto     string::size_type  i;
    auto     char               c;
    auto     char               c1;
    auto     string::size_type  len = data.length();
    auto     string             ret;

    for (i = 0; i < len; ++i)
    {
        c = (char) cvt.find(data[i]);
        ++i;
        c1 = (char) cvt.find(data[i]);
        c = (c << 2) | ((c1 >> 4) & 0x3);
        ret.append(1, c);
        if (++i < len)
        {
            c = data[i];
            if (fillchar == c)
                break;

            c = (char) cvt.find(c);
            c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf);
            ret.append(1, c1);
        }

        if (++i < len)
        {
            c1 = data[i];
            if (fillchar == c1)
                break;

            c1 = (char) cvt.find(c1);
            c = ((c << 6) & 0xc0) | c1;
            ret.append(1, c);
        }
    }

    return(ret);
}
----------------end--------------------------------

and this is the base64.h

#ifndef Base64_H
#define Base64_H

#include <string>
using std::string;

class Base64
{
public:
    static string encode(string data);
    static string decode(string data);
};

#endif

------------------------end------------------
Maybe this will help. That's not a C++ code, but pure C, so it should work under any compiler. It really does not need any special headers/libraries/etc. except standard C string (for strchr function).

But that's for x86 processor - for other processors you will have to modify the bit operations.

The code is not perfect - you may think of making it more reliable by adding parameters checking, for example (I stripped off the project-specific code that has been doing this stuff).

------------------------------ code starts here ----------------------

static char* _cpBase64Encoding =
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";


void Base64Encode( char* cpInput, char* cpOutput )
{
  int nIdx[ 4 ];  // will contain the indices of coded letters in
                  // _cpBase64Encoding string; valid values [0..64]; the value
                  // of 64 has special meaning - the padding symbol

  // process the data (3 bytes of input provide 4 bytes of output)
  while ( '\0' != *cpInput )
  {
    nIdx[0] = ((*cpInput) & 0xFC)>>2;
    nIdx[1] = ((*cpInput) & 0x03)<<4;
    cpInput++;
    if ( '\0' != *cpInput )
    {
      nIdx[1] |= ((*cpInput) & 0xF0)>>4;
      nIdx[2]  = ((*cpInput) & 0x0F)<<2;
      cpInput++;
      if ( '\0' != (*cpInput) )
      {
        nIdx[2] |= ((*cpInput) & 0xC0) >> 6;
        nIdx[3]  = (*cpInput) & 0x3F;
        cpInput++;
      }
      else
        nIdx[3] = 64;
    }
    else
    { // refer to padding symbol '='
      nIdx[2] = 64;
      nIdx[3] = 64;
    }

    *(cpOutput+0) = *(_cpBase64Encoding + nIdx[0]);
    *(cpOutput+1) = *(_cpBase64Encoding + nIdx[1]);
    *(cpOutput+2) = *(_cpBase64Encoding + nIdx[2]);
    *(cpOutput+3) = *(_cpBase64Encoding + nIdx[3]);
    cpOutput += 4;
  }
 
  // set this to terminate output string
  *cpOutput = '\0';

  return;
}




void Base64Decode( char* cpInput, char* cpOutput )
{
  int nIdx[ 4 ];  // will contain the indices of coded letters in
                  // _cpBase64Encoding string; valid values [0..64]; the value
                  // of 64 has special meaning - the padding symbol

  // process the data (3 bytes of input provide 4 bytes of output
  while ( '\0' != *cpInput )
  {
    nIdx[ 0 ] = nIdx[ 1 ] = nIdx[ 2 ] = nIdx[ 3 ] = 64;
    nIdx[0] = (strchr( _cpBase64Encoding, (*cpInput) ) - _cpBase64Encoding);
    cpInput++;
    if ( '\0' != *cpInput )
    {
      nIdx[1] = (strchr( _cpBase64Encoding, (*cpInput) ) - _cpBase64Encoding);
      cpInput++;
      if ( '\0' != (*cpInput) )
      {
        nIdx[2] = (strchr( _cpBase64Encoding, (*cpInput) ) - _cpBase64Encoding);
        cpInput++;
        if ( '\0' != (*cpInput) )
        {
          nIdx[3] = (strchr( _cpBase64Encoding, (*cpInput) ) - _cpBase64Encoding);
          cpInput++;
        }
      }
    }

    if ( nIdx[3] == 64 ) nIdx[3] = 0;
    if ( nIdx[2] == 64 ) nIdx[2] = 0;
    if ( nIdx[1] == 64 ) nIdx[1] = 0;

    *(cpOutput+0) = (char)((nIdx[0]<<2) | (nIdx[1]>>4));
    *(cpOutput+1) = (char)((nIdx[1]<<4) | (nIdx[2]>>2));
    *(cpOutput+2) = (char)((nIdx[2]<<6) | nIdx[3]);
    cpOutput += 3;
  }
 
  // set this to terminate output string
  *cpOutput = '\0';

  return;
}

------------------------------ the end ----------------------

Hope this helps.
Sorry, when posting the code has not yet seen your last question :-)
Avatar of urif

ASKER

thanks,

what do you mean by:

"except standard C string"  which .h are you talking about?

thanks again
Avatar of urif

ASKER

sorry, but whatever i pass to the function (char, *char, &char, **char, you name it) it throws me out with an enhandled exception in your code
ASKER CERTIFIED SOLUTION
Avatar of s_andrew
s_andrew

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of urif

ASKER

if you are reding this after i posted the OK for the question, i'm trying to pass a var of type BYTE [16], in other words i have an unsigned char* and when decoding the string (that i asume is coding it right) it returns garbage, not the original string.

some other times it throws an exception.


any ideas?