Base64演算法將輸入的字串或一段資料編碼成只含有{''A''-''Z'', ''a''-''z'', ''0''-''9'', ''+'', ''/''}這64個字元的串,''=''用於填充。其編碼的方法是,將輸入資料流每次取6 bit,用此6 bit的值(0-63)作為索引去查表,輸出相應字元。這樣,每3個位元組將編碼為4個字元(3×8 → 4×6);不滿4個字元的以''=''填充。
貼在這裡,以後忘了的時候方便查閱:)
編碼的過程是這樣的:
第一個字元通過右移2位獲得第一個目標字元的Base64表位置,根據這個數值取到表上相應的字元,就是第一個目標字元。
然後將第一個字元左移4位加上第二個字元右移4位,即獲得第二個目標字元。
再將第二個字元左移2位加上第三個字元右移6位,獲得第三個目標字元。
最後取第三個字元的右6位即獲得第四個目標字元。
在以上的每一個步驟之後,再把結果與 0x3F 進行 AND 位操作,就可以得到編碼後的字元了。
實現如下:
00001 00013 #include <ctype.h>00014 00015 00016 static const char base64digits[] =00017 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";00018 00019 #define BAD -100020 static const char base64val[] = {00021 BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,00022 BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,00023 BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD, 62, BAD,BAD,BAD, 63,00024 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,BAD,BAD, BAD,BAD,BAD,BAD,00025 BAD, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,00026 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,BAD, BAD,BAD,BAD,BAD,00027 BAD, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,00028 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,BAD, BAD,BAD,BAD,BAD00029 };00030 #define DECODE64(c) (isascii(c) ? base64val[c] : BAD)00031 00039 void to64frombits(unsigned char *out, const unsigned char *in, int inlen)00040 {00041 for (; inlen >= 3; inlen -= 3)00042 {00043 *out++ = base64digits[in[0] >> 2];00044 *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)];00045 *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)];00046 *out++ = base64digits[in[2] & 0x3f];00047 in += 3;00048 }00049 00050 if (inlen > 0)00051 {00052 unsigned char fragment;00053 00054 *out++ = base64digits[in[0] >> 2];00055 fragment = (in[0] << 4) & 0x30;00056 00057 if (inlen > 1)00058 fragment |= in[1] >> 4;00059 00060 *out++ = base64digits[fragment];00061 *out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c];00062 *out++ = '=';00063 }00064 00065 *out = '/0';00066 }00067 00075 int from64tobits(char *out, const char *in)00076 {00077 int len = 0;00078 register unsigned char digit1, digit2, digit3, digit4;00079 00080 if (in[0] == '+' && in[1] == ' ')00081 in += 2;00082 if (*in == '/r')00083 return(0);00084 00085 do {00086 digit1 = in[0];00087 if (DECODE64(digit1) == BAD)00088 return(-1);00089 digit2 = in[1];00090 if (DECODE64(digit2) == BAD)00091 return(-1);00092 digit3 = in[2];00093 if (digit3 != '=' && DECODE64(digit3) == BAD)00094 return(-1);00095 digit4 = in[3];00096 if (digit4 != '=' && DECODE64(digit4) == BAD)00097 return(-1);00098 in += 4;00099 *out++ = (DECODE64(digit1) << 2) | (DECODE64(digit2) >> 4);00100 ++len;00101 if (digit3 != '=')00102 {00103 *out++ = ((DECODE64(digit2) << 4) & 0xf0) | (DECODE64(digit3) >> 2);00104 ++len;00105 if (digit4 != '=')00106 {00107 *out++ = ((DECODE64(digit3) << 6) & 0xc0) | DECODE64(digit4);00108 ++len;00109 }00110 }00111 } while (*in && *in != '/r' && digit4 != '=');00112 00113 return (len);00114 }