Base64編碼的原理及實現(源碼)

    Base64編碼在郵件中最爲常見,呵呵,因爲我最近就是在做郵箱報警,SMTP驗證就是Base64編碼用戶名和密碼進行驗證的,並且附件也是要轉換成base64編碼的數據,然後再發送的。該編碼使用64個明文來編碼任意的二進制文件,它裏面只使用了A-Z,a-z,0-9,+,/這64個字符。編碼裏面還有“=”號啊,不過等號不屬於編碼字符,而是填充字符。

    我在網上查了很多關於Base64編碼代碼,大都比較的複雜和冗長,還有,Base64編碼函數內儘量不要有strlen()這個函數,因爲當我獲取圖片數據時,明明read返回54,strlen卻爲4,可能中間有些'\0'吧。哭所以,一氣之下,就自己寫了一個。

 

一、base64編碼原理:

    1)base64的編碼都是按字符串長度,以每3個8bit的字符爲一組,

    2)然後針對每組,首先獲取每個字符的ASCII編碼,
    3)然後將ASCII編碼轉換成8bit的二進制,得到一組3*8=24bit的字節
    4)然後再將這24bit劃分爲4個6bit的字節,並在每個6bit的字節前面都填兩個高位0,得到4個8bit的字節
    5)然後將這4個8bit的字節轉換成10進制,對照Base64編碼表 ,得到對應編碼後的字符。

 

二、源碼:

static const char* base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

//chsrc爲源數據,chdes爲Base64編碼後的數據,len爲數據長度

void Base64_Code(unsigned char* chsrc, unsigned char* chdes, int len)
{
      unsigned char char_array_3[3], char_array_4[4];
      int i = 0, j = 0;
 
      while(len--)
      {
            char_array_3[i++] = *(chsrc++);
            if(3 == i)
            {
                  char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
                  char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
                  char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
                  char_array_4[3] = char_array_3[2] & 0x3f;

                  for(i = 0; i < 4; i++)
                        *(chdes+i) = base64_chars[char_array_4[i]];
    
                  i = 0;
                 chdes += 4;
            }
      }

      if(i)
      {
             for(j = i; j < 3; j++)
             char_array_3[j] = '\0';
  
            char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
            char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
            char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
            char_array_4[3] = char_array_3[2] & 0x3f;
  
            for(j = 0; j < (i+1); j++)
                  *(chdes++) = base64_chars[char_array_4[j]];
   
            while((3 > i++))
                  *(chdes++) = '=';
      }
 
      *chdes = '\0';
      return;
}   

 

順便用C++模仿寫一個吧(因爲我是用作郵箱報警的,所以,Base64編碼是Email中的一個操作):

string Email::base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len)
{
     string dest;
     int i = 0, j = 0;
     unsigned char char_array_3[3], char_array_4[4];

     while(in_len--)
     {
          char_array_3[i++] = *(bytes_to_encode++);
          if (3 == i) 
          {
               char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
               char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
               char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
               char_array_4[3] = char_array_3[2] & 0x3f;

               for(i = 0; i < 4; i++)
                   dest += base64_chars[char_array_4[i]];
               i = 0;
            }
     }

     if (i)
     {
          for(j = i; j < 3; j++)
              char_array_3[j] = '\0';

          char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
          char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
          char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
          char_array_4[3] = char_array_3[2] & 0x3f;

          for (j = 0; j < (i + 1); j++)
               dest += base64_chars[char_array_4[j]];

          while((i++ < 3))
               dest += '=';  
      }

     return dest;
}

      Base64解碼我就不管了,因爲一般用到的情況很少,而且,最重要的是,我目前還用不到。大笑

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章