简介
BASE64是目前最常见的编码算法,用于将二进制数据表示为可打印字符串,具体的转换方式由一个64个字符组成的查找表决定,但都是将三个字节(24bit)转换为4个字符(base64中一个字符可以表示6bit的状态,所以也是24bit)
特征
base64主要的特征一个是输出的结果是大量乱七八糟的可打印字符串,事实上如果看到大量乱七八糟的字符串都可以怀疑是base系列,因为如果是其他加密算法基本上不会输出为可打印字符串
另一个特征就是base64算法会带一个64个字符组成的查找表
实现
主要是实现3个8bit对6个4bit的映射,编解码都差不多,下面三张wikipedia的图很好的解释了映射逻辑



如果输入不是3的倍数就对缺的部分补padding,默认标准是补”=”
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 26 27
   | string encode(string input) {     string res = "";     for (size_t i = 0; i < input.size(); i += 3)     {         uint32_t tmp = 0;         int pad = 3;         for (size_t j = i; j < i + 3; j++)         {             if (j < input.size())             {                 tmp = (tmp << 8) | input[j];                 pad--;             }             else                 tmp <<= 8;         }         for (int j = 0; j < 4 - pad; j++)         {             uint32_t mask = (1 << 6) - 1;             res += base64Table[(tmp >> (6 * (3 - j))) & mask];         }         while (pad--)             res += paddingCode;     }     return res; }
   | 
 
解码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | string decode(string input) {   string res = "";   for (size_t i = 0; i < input.size(); i += 4) {     uint32_t tmp = 0;     int validChars = 0;     for (size_t j = i; j < i + 4 && j < input.size() && input[j] != paddingCode;          j++) {       tmp = (tmp << 6) | find(base64Table, input[j]);       validChars++;     }     if (validChars >= 2) {       int shiftBits = (4 - validChars) * 6;       tmp <<= shiftBits;
        res += (char)((tmp >> 16) & 0xFF);       if (validChars >= 3)         res += (char)((tmp >> 8) & 0xFF);       if (validChars >= 4)         res += (char)(tmp & 0xFF);     }   }   return res; }
  | 
 
完整代码
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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
   | #include <bits/stdc++.h> using namespace std; string base64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; char paddingCode = '='; char find(string &table, char ch) {     for (size_t i = 0; i < table.size(); i++)     {         if (table[i] == ch)             return (char)i;     }     return -1; } string encode(string input) {     string res = "";     for (size_t i = 0; i < input.size(); i += 3)     {         uint32_t tmp = 0;         int pad = 3;         for (size_t j = i; j < i + 3; j++)         {             if (j < input.size())             {                 tmp = (tmp << 8) | input[j];                 pad--;             }             else                 tmp <<= 8;         }         for (int j = 0; j < 4 - pad; j++)         {             uint32_t mask = (1 << 6) - 1;             res += base64Table[(tmp >> (6 * (3 - j))) & mask];         }         while (pad--)             res += paddingCode;     }     return res; } string decode(string input) {   string res = "";   for (size_t i = 0; i < input.size(); i += 4) {     uint32_t tmp = 0;     int validChars = 0;     for (size_t j = i; j < i + 4 && j < input.size() && input[j] != paddingCode;          j++) {       tmp = (tmp << 6) | find(base64Table, input[j]);       validChars++;     }     if (validChars >= 2) {       int shiftBits = (4 - validChars) * 6;       tmp <<= shiftBits;
        res += (char)((tmp >> 16) & 0xFF);       if (validChars >= 3)         res += (char)((tmp >> 8) & 0xFF);       if (validChars >= 4)         res += (char)(tmp & 0xFF);     }   }   return res; } int main() {     string inputCode;     getline(cin, inputCode);     cout << encode(inputCode) << "\n";     cout << decode(encode(inputCode));     return 0; }
   | 
 
reference
wikipedia-base64