VC BASE64 encoding and decoding use of detailed _c language

Source: Internet
Author: User
Tags base64 openssl

BASE64 can be used to encode binary byte sequence data into text consisting of an ASCII character sequence. The complete BASE64 definition is visible RFC1421 and RFC2045. The encoded data is slightly longer than the original data, which is 4/3 of the original. In e-mail, according to RFC822, you need to add a carriage return line for every 76 characters.

At the time of conversion, the three byte data is placed in a 24bit buffer, and the first byte occupies the highest position. When the data is less than 3byte, the remaining bit in the buffer is replenished with 0. Then, each time 6 bit is taken out, the characters in abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789+/are selected as the encoded output according to their value. Continue until all input data conversion is complete. If there are two input data left, add 1 "=" After the code result, and add 2 "=" After the end of the code, and if there is no data left, do not add anything, so as to ensure the correctness of the data restore.

Base64_api.h File Contents

/*----------------------------------------------------------file name: base64_api.h Author: Qin Jianhui msn:splashcn@msn.com

  Current version: V1.1 history version: V1.1 May 11, 2010 corrected bug for BASE64 decoding.

V1.0 May 07, 2010 Complete the official version.  Function Description: BASE64 encoding and decoding interface function: Base64_encode base64_decode Description: 1.
  Reference openssl-1.0.0.
  2. Improve the interface so that it adapts to the TCHAR string.
 3. Fixed the defect that the padding byte was not removed when decoding the Evp_decodeblock function. ------------------------------------------------------------* * * #pragma once #include "stdafx.h" #include < windows.h> #ifdef __cplusplus extern "C" {#endif/* feature: Converts binary data to BASE64 encoded string parameter description: InputBuffer: Binary data to encode Inputco
UNT: Data length OutputBuffer: Store converted BASE64 encoded string return value:-1: Parameter error >=0: Valid encoding length (number of characters), excluding string terminator.

Note: equivalent to OpenSSL evp_encodeblock function/int base64_encode (const byte* inputbuffer, int inputcount, tchar* outputbuffer);
  /* Feature: Converts BASE64 encoded string to binary Data parameter description: INPUTBUFFER:BASE64 encoded string inputcount: Encoding Length (number of characters), should be a multiple of 4. OutputBuffer: Store converted binary Data return value:-1: Parameter Error-2: Data error >=0: Converted byte number remark: equivalent to OpenSSL evp_decodeblockfunction */int base64_decode (const tchar* inputbuffer, int inputcount, byte* outputbuffer);
 #ifdef __cplusplus} #endif

Base64_api.cpp File Contents

#pragma once #include "stdafx.h" #include "base64_api.h" static const char* DATA_BIN2ASCII = "abcdefghijklmnopqrstuvwx

yzabcdefghijklmnopqrstuvwxyz0123456789+/";
  int Base64_encode (const byte* inputbuffer, int inputcount, tchar* outputbuffer) {int i;

  BYTE B0, B1, B2; if ((InputBuffer = NULL) | |
  (Inputcount < 0))  {return-1;
      Parameter Error} if (OutputBuffer!= NULL) {for (i = inputcount; i > 0; i = 3) {if (I >= 3)
        {//Convert 3 Byte data to 4 ASCII characters b0 = *inputbuffer++;
        B1 = *inputbuffer++;

        b2 = *inputbuffer++;
        *outputbuffer++ = data_bin2ascii[b0 >> 2]; *outputbuffer++ = data_bin2ascii[(B0 << 4) | (B1 >> 4))
        & 0x3F]; *outputbuffer++ = data_bin2ascii[(B1 << 2) | (B2 >> 6))
        & 0x3F];
      *outputbuffer++ = data_bin2ascii[b2 & 0x3F];
        else {b0 = *inputbuffer++; if (i = = 2) B1 = *inputbuffer++;

      else B1 = 0;  *outputbuffer++ = data_bin2ascii[b0 >> 2]; *outputbuffer++ = data_bin2ascii[(B0 << 4) | (B1 >> 4))
        & 0x3F]; *outputbuffer++ = (i = = 1)?
        TEXT (' = '): data_bin2ascii[(B1 << 2) & 0x3F];
      *outputbuffer++ = TEXT (' = ');  }//end for I *outputbuffer++ = TEXT ('/0 ');  Add string end Tag} return ((Inputcount + 2)/3) * 4; Returns the number of valid characters} #define B64_EOLN 0xF0//newline/n #define B64_CR 0xf1//Enter/R #define B64_EOF 0xf2//hyphen  -#define B64_WS 0xe0//or spaces (/T, space) #define B64_ERROR 0xFF//Error characters #define B64_NOT_BASE64 (A) (((a) |0x13) = = 0xf3) static const BYTE data_ascii2bin[128] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0xf0,0xff,0xff,0x F1,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xE0,0xFF,0xFF, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3e,0xff,0xf2,0xff,0x3f, 0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c, 0x3d,0xff,0xff,0xFf,0x00,0xff,0xff, 0xff,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, 0x0F,0x10, 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0xff,0xff,0xff,0xff,0xff, 0xff,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20, 0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28, 0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0xff,0xff,

0XFF,0XFF};
  int Base64_decode (const tchar* inputbuffer, int inputcount, byte* outputbuffer) {int I, J;
  BYTE B[4];

  TCHAR ch; if ((InputBuffer = NULL) | |
  (Inputcount < 0))  {return-1;
    Parameter error}//removal of head whitespace character while (Inputcount > 0) {ch = *inputbuffer; if ((Ch < 0) | |
    (Ch >= 0x80))  {return-2;
        Data error, not in ASCII character encoding range} else {if (data_ascii2bin[ch] = b64_ws) {inputbuffer++;
      inputcount--;
      } else {break;
    }}///Remove trailing whitespace characters, carriage return newline characters, hyphen while (Inputcount >= 4) {ch = inputbuffer[inputcount-1]; If((Ch < 0) | |
    (Ch >= 0x80))  {return-2;
      Data error, not in ASCII character encoding range} else {if (B64_not_base64 (Data_ascii2bin[ch])) {inputcount--;
      } else {break;  }}///String length must be multiples of 4 if ((inputcount% 4)!= 0) {return-2; Data Error} if (OutputBuffer!= NULL) {for (i = 0; i < inputcount i + 4) {for (j = 0; J < 4 ;
        J + +) {ch = *inputbuffer++; if ((Ch < 0) | |
        (Ch >= 0x80))  {return-2;
            Data error, not in ASCII character encoding range} else {if (ch = =)//Discover fill character in BASE64 encoding {
          Break
            else {B[j] = Data_ascii2bin[ch];  if (B[j] & 0x80) {return-2;
        Data error, invalid BASE64 encoding character}}///End for J if (j = = 4) { *outputbuffer++ = (B[0] << 2)|
        (B[1] >> 4); *outputbuffer++ = (B[1] << 4) |
        (B[2] >> 2); *outputbuffer++ = (b[2] << 6) |
      B[3]; else if (j = = 3) {//There are 1 padding bytes *outputbuffer++ = (B[0] << 2) |
        (B[1] >> 4); *outputbuffer++ = (B[1] << 4) |

        (B[2] >> 2);
      Return (I >> 2) * 3 + 2; else if (j = = 2) {//There are 2 padding bytes *outputbuffer++ = (B[0] << 2) |

        (B[1] >> 4);
      Return (I >> 2) * 3 + 1;  else {return-2;
Data error, invalid BASE64 encoded character}//end to I} return (Inputcount >> 2) * 3;
 }

The above method can be used to convert binary data into visible characters for delivery.

So how to use it? Give the following two examples

First: Convert a picture to txt text and save it

Select an image file and convert it to text save to _t ("D:\\2.txt"
void Ctextpicdlg::onbnclickedbutton2 ()
{
  //TODO: Add control notification Handler code here
  CFileDialog file (TRUE, ". jpg", "");
  if (file. DoModal () = = Idok)
  {
    CFile data (file. GetPathName (), cfile::modereadwrite);
    int len = data. GetLength ();
    BYTE *DV;
    DV = (BYTE *) malloc (len*sizeof (Byte));
    Data. Read (DV, Len);
    Data. Close ();
    int slen = (LEN/3) * 4;
    Slen + = ten;
    TCHAR * TC;
    TC = (TCHAR *) malloc (slen);
    Slen = Base64_encode (DV, Len, TC);
    CFile Save (_t ("D:\\2.txt"), Cfile::modecreate | Cfile::modewrite);
    Save. Write (TC, slen);
    Save. Close ();
    Free (TC);
    Free (DV);
  }
}

The second example restores a text file to an image

void Ctextpicdlg::onbnclickedbutton3 () {//TODO: Add control Notification Handler code CFileDialog file (TRUE, ". txt", "") here; if (file. DoModal () = = Idok) {CFile data (file.
    GetPathName (), cfile::modereadwrite); int len = data.
    GetLength ();
    TCHAR *DV;
    DV = (TCHAR *) malloc (len*sizeof (TCHAR)); Data.
    Read (DV, Len); Data.
    Close ();
    int slen = (LEN/4) * 3;
    Slen + 10;
    BYTE * TC;
    TC = (BYTE *) malloc (Slen);
    Base64_decode (DV, Len, TC);
    Directly in the memory to build CImage, you need to use the IStream interface, how to use//to build the memory environment hglobal hglobal = GlobalAlloc (gmem_moveable, Slen);
    void * PData = GlobalLock (hglobal); memcpy (PData, TC, Slen);
    Copy bitmap data in GlobalUnlock (HGLOBAL);
    Create IStream IStream * pstream = NULL;
    if (CreateStreamOnHGlobal (Hglobal, TRUE, &pstream)!= S_OK) return;
    Use CImage to load bitmap memory CImage img; if (SUCCEEDED (IMG).
       Load (Pstream))) {CCLIENTDC DC (this); Draw the IMG directly on the dialog box using the image constructed inside.
    Draw (DC.M_HDC, 0, 0, 500, 300);
   }  Free memory pstream->release ();
    GlobalFree (HGLOBAL);
    If you want to save the image file, use the following code//cfiledialog savefile (FALSE, ". jpg", ""); if (savefile. DoModal () ==idok)//{//CFile Save (SaveFile. GetPathName (), Cfile::modecreate |
    Cfile::modewrite); Save.
    Write (TC, Slen); Save.
    Close ();
    Free (TC);
  Free (DV);

 }
}

At this point, the use of Base64 transcoding to show the way to save the display picture, even if it is successful!

Let's look at an example of a base64 code decoding.

First, the code.

Const BYTE BASE64VALTAB[65] = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789+/";
    #define AVAL (x) base64valtab[x] int cseebase64dlg::encodebase64 (char * pinput, char * poutput) {int i = 0;
    int loop = 0;
    int remain = 0;
    int idstlen = 0;

    int isrclen = (int) strlen (pinput);
    loop = ISRCLEN/3;

    remain = isrclen%3; Also can encode native char one by one as decode how//But because all of char native

    D so encode 3-chars one time is easier.
        for (i=0 i < loop; i++) {BYTE A1 = (pinput[i*3] >> 2); BYTE A2 = ((Pinput[i*3] & 0x03) << 4) |
        (Pinput[i*3+1] >> 4)); BYTE a3 = ((Pinput[i*3+1] & 0x0f) << 2) |
        ((pinput[i*3+2] & 0xc0) >> 6);

        BYTE A4 = (pinput[i*3+2] & 0x3F);
        POUTPUT[I*4] = aval (A1);
        Poutput[i*4+1] = Aval (A2);
        POUTPUT[I*4+2] = Aval (A3);
    POUTPUT[I*4+3] = Aval (A4); } IDStlen = i*4;
        if (remain = = 1) {//should pad two equal sign i = iSrcLen-1;
        BYTE A1 = (Pinput[i] >> 2);
        
        BYTE A2 = ((Pinput[i] & 0x03) << 4);
        poutput[idstlen++] = aval (A1);
        poutput[idstlen++] = Aval (A2);
        poutput[idstlen++] = ' = ';
        poutput[idstlen++] = ' = ';
    Poutput[idstlen] = 0x00;
        else if (remain = 2) {//should pad one equal sign i = iSrcLen-2;
        BYTE A1 = (Pinput[i] >> 2); BYTE A2 = ((Pinput[i] & 0x03) << 4) |
        (Pinput[i+1] >> 4));

        BYTE a3 = ((Pinput[i+1] & 0x0f) << 2);
        poutput[idstlen++] = aval (A1);
        poutput[idstlen++] = Aval (A2);
        poutput[idstlen++] = Aval (A3);
        poutput[idstlen++] = ' = ';
    Poutput[idstlen] = 0x00;
    else {//Just division by 3 Poutput[idstlen] = 0x00;
return Idstlen; }

The following is decoding

Const BYTE base64idxtab[128] = {255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 25
5,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255, 62, 255,255,255, 63, 52,53,54,55, 56,57,58,59, 60, 61,255,255, 255,255,255,255, 255,0,1,2, 3,4,5,6, 7,8,9,10, 11,12,13,14, 15,16 , 17, 18, 19,20,21,22, 23,24,25,255, 255,255,255,255, 255,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, 41,42

, 43, 44, 45,46,47,48, 49,50,51,255, 255,255,255,255};
    #define BVAL (x) base64idxtab[x] int Cseebase64dlg::D ecodeBase64 (char * pinput, char * poutput) {int i = 0;
    int icnt = 0;

    int isrclen = (int) strlen (pinput);

    char * p = poutput;
        for (i=0 i < Isrclen i++) {if (pinput[i) > 127) Continue;

        if (pinput[i] = = ' = ') return p-poutput+1;
        BYTE a = Bval (Pinput[i]);
        
        if (a = = 255) continue;
     Switch (icnt) {case 0:       {*p = a << 2;
            icnt++;

        } break;
                Case 1: {*p++ |= a >> 4;
                *p = a << 4;
            icnt++;

        } break;
                Case 2: {*p++ |= a >> 2;
                *p = a << 6;
            icnt++;
        } break;
                Case 3: {*p++ |= A;
            icnt = 0;
        } break;
    } *p = 0x00;
return p-poutput; }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.