00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <cstring>
00020 #include <cstdlib>
00021
00022 #include "base64.h"
00023
00024 static char base64_table[] =
00025 {
00026 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
00027 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
00028 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
00029 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
00030 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
00031 };
00032 static char base64_pad = '=';
00033
00034 unsigned char *php_base64_encode(const unsigned char *str, int length, int *ret_length) {
00035 const unsigned char *current = str;
00036 int i = 0;
00037 unsigned char *result = (unsigned char *)malloc(((length + 3 - length % 3) * 4 / 3 + 1) * sizeof(char));
00038
00039 while (length > 2) {
00040 result[i++] = base64_table[current[0] >> 2];
00041 result[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
00042 result[i++] = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
00043 result[i++] = base64_table[current[2] & 0x3f];
00044
00045 current += 3;
00046 length -= 3;
00047 }
00048
00049
00050 if (length != 0) {
00051 result[i++] = base64_table[current[0] >> 2];
00052 if (length > 1) {
00053 result[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
00054 result[i++] = base64_table[(current[1] & 0x0f) << 2];
00055 result[i++] = base64_pad;
00056 }
00057 else {
00058 result[i++] = base64_table[(current[0] & 0x03) << 4];
00059 result[i++] = base64_pad;
00060 result[i++] = base64_pad;
00061 }
00062 }
00063 if(ret_length) {
00064 *ret_length = i;
00065 }
00066 result[i] = '\0';
00067 return result;
00068 }
00069
00070
00071 unsigned char *php_base64_decode(const unsigned char *str, int length, int *ret_length) {
00072 const unsigned char *current = str;
00073 int ch, i = 0, j = 0, k;
00074
00075 static short reverse_table[256];
00076 static int table_built;
00077 unsigned char *result;
00078
00079 if (++table_built == 1) {
00080 char *chp;
00081 for(ch = 0; ch < 256; ch++) {
00082 chp = strchr(base64_table, ch);
00083 if(chp) {
00084 reverse_table[ch] = chp - base64_table;
00085 } else {
00086 reverse_table[ch] = -1;
00087 }
00088 }
00089 }
00090
00091 result = (unsigned char *)malloc(length + 1);
00092 if (result == NULL) {
00093 return NULL;
00094 }
00095
00096
00097 while ((ch = *current++) != '\0') {
00098 if (ch == base64_pad) break;
00099
00100
00101
00102
00103
00104
00105
00106
00107 if (ch == ' ') ch = '+';
00108
00109 ch = reverse_table[ch];
00110 if (ch < 0) continue;
00111
00112 switch(i % 4) {
00113 case 0:
00114 result[j] = ch << 2;
00115 break;
00116 case 1:
00117 result[j++] |= ch >> 4;
00118 result[j] = (ch & 0x0f) << 4;
00119 break;
00120 case 2:
00121 result[j++] |= ch >>2;
00122 result[j] = (ch & 0x03) << 6;
00123 break;
00124 case 3:
00125 result[j++] |= ch;
00126 break;
00127 }
00128 i++;
00129 }
00130
00131 k = j;
00132
00133 if (ch == base64_pad) {
00134 switch(i % 4) {
00135 case 0:
00136 case 1:
00137 free(result);
00138 return NULL;
00139 case 2:
00140 k++;
00141 case 3:
00142 result[k++] = 0;
00143 }
00144 }
00145 if(ret_length) {
00146 *ret_length = j;
00147 }
00148 result[k] = '\0';
00149 return result;
00150 }
00151