blob: 829b952c2d782f968827c6f9bf8a1a11a62e6572 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "base64.h"
unsigned char *base64_encode(unsigned char *str) {
long len;
long str_len;
unsigned char *res;
int i,j;
// define the base64 table
unsigned char *base64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// calculate the length of the base64 encoded str
str_len = strlen(str);
if (str_len % 3 == 0)
len = str_len/3*4;
else
len = (str_len/3+1)*4;
res = malloc(sizeof(unsigned char)*len+1);
res[len] = '\0';
// encode in groups of three 8-bit characters
for(i=0,j=0;i<len-2;j+=3,i+=4) {
res[i] = base64_table[str[j]>>2]; // take out the first 6 digits of the first character and find the corresponding character
res[i+1] = base64_table[(str[j]&0x3)<<4 | (str[j+1]>>4)]; // combine the last four digits of the first character with the first four digits of the second character and find the corresponding character
res[i+2] = base64_table[(str[j+1]&0xf)<<2 | (str[j+2]>>6)]; // combine the last 4 digits of the second character with the first 2 digits of the third character and find the corresponding character
res[i+3] = base64_table[str[j+2]&0x3f]; // take out the last 6 digits of the third character and find the corresponding character
}
switch(str_len % 3){
case 1:
res[i-2] = '=';
res[i-1] = '=';
break;
case 2:
res[i-1] = '=';
break;
}
return res;
}
unsigned char *base64_decode(unsigned char *code) {
// according to the base64 table, find the corresponding decimal data in characters
int table[] = {0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,62,0,0,0,
63,52,53,54,55,56,57,58,
59,60,61,0,0,0,0,0,0,0,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,0,0,0,0,0,0,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
};
long len;
long str_len;
unsigned char *res;
int i,j;
// calculates the length of the decoded str
len = strlen(code);
// judge whether the encoded str contains '='
if(strstr(code,"=="))
str_len = len/4*3-2;
else if(strstr(code,"="))
str_len = len/4*3-1;
else
str_len = len/4*3;
res = malloc(sizeof(unsigned char)*str_len+1);
res[str_len] = '\0';
for(i=0,j=0;i < len-2;j+=3,i+=4) {
res[j] = ((unsigned char)table[code[i]])<<2 | (((unsigned char)table[code[i+1]])>>4);
res[j+1] = (((unsigned char)table[code[i+1]])<<4) | (((unsigned char)table[code[i+2]])>>2);
res[j+2] = (((unsigned char)table[code[i+2]])<<6) | ((unsigned char)table[code[i+3]]);
}
return res;
}