C语言 实现Base64编码
#include <stdio.h>
#include <stdlib.h>
struct Base64Code {
unsigned char* data;
unsigned long long int size;
};
int main(int argc,char* argv[]);
struct Base64Code Base64Encode(unsigned char* data, unsigned long long int size);
struct Base64Code Base64Decode(unsigned char* data, unsigned long long int size);
int main(int argc,char* argv[]){
struct Base64Code a = Base64Encode((unsigned char*) "0123456789", 9);
printf("%d\t %s \n", a.size, a.data);
struct Base64Code b = Base64Decode((unsigned char*)a.data, a.size);
printf("%d\t %s \n", b.size, b.data);
a = Base64Encode((unsigned char*) "98643210", 9);
printf("%d\t %s \n", a.size, a.data);
b = Base64Decode((unsigned char*)a.data, a.size);
printf("%d\t %s \n", b.size, b.data);
a = Base64Encode((unsigned char*) "1234", 4);
printf("%d\t %s \n", a.size, a.data);
b = Base64Decode((unsigned char*)a.data, a.size);
printf("%d\t %s \n", b.size, b.data);
return 0;
}
struct Base64Code Base64Encode(unsigned char* data, unsigned long long int size) {
struct Base64Code ReturnData;
ReturnData.size = 0;
ReturnData.data = NULL;
if (data == NULL || size == 0) {
return ReturnData;
}
ReturnData.data = (unsigned char*)malloc((size % 3 == 0) ? (size * 8 / 6 + 1) : (4 - (size % 3) + size * 8 / 6 + 1));
if (ReturnData.data == NULL) {
return ReturnData;
}
ReturnData.data[(size % 3 == 0) ? (size * 8 / 6) : (4 - (size % 3) + size * 8 / 6)] = 0; ReturnData.size = size - (size % 3);
char Base64Data[64]; unsigned long long int temp; unsigned long long int i = 0;
unsigned long long int j = 0; Base64Data[62] = '+'; Base64Data[63] = '/';
for (i = 65; i < 91; i++) {
Base64Data[j] = i;
j++;
}
for (i = 97; i < 123; i++) {
Base64Data[j] = i;
j++;
}
for (i = 48; i < 58; i++) {
Base64Data[j] = i;
j++;
}
char Buffer[4]; j = 0;
for (i = 0; i < size; i = i + 3) {
Buffer[0] = Base64Data[data[i] >> 2];
Buffer[1] = (((unsigned char)(data[i] << 6)) >> 2);
if (i == ReturnData.size && size - i == 1) {
ReturnData.data[j] = Buffer[0]; j++;
ReturnData.data[j] = Base64Data[Buffer[1]]; j++;
ReturnData.data[j] = '='; j++;
ReturnData.data[j] = '=';
break;
}
Buffer[1] = Base64Data[Buffer[1] + (data[i + 1] >> 4)];
Buffer[2] = (((unsigned char)(data[i + 1] << 4)) >> 2);
if (i == ReturnData.size && size - i == 2) {
ReturnData.data[j] = Buffer[0]; j++;
ReturnData.data[j] = Buffer[1]; j++;
ReturnData.data[j] = Base64Data[Buffer[2]]; j++;
ReturnData.data[j] = '=';
break;
}
Buffer[2] = Base64Data[Buffer[2] + (data[i + 2] >> 6)];
Buffer[3] = Base64Data[(((unsigned char)(data[i + 2] << 2)) >> 2)];
for (temp = j; temp < j + 4; temp++) {
ReturnData.data[temp] = Buffer[temp - j];
}
j = temp;
}
ReturnData.size = (size % 3 == 0) ? (size * 8 / 6) : (4 - (size % 3) + size * 8 / 6);
return ReturnData;
}
struct Base64Code Base64Decode(unsigned char* data, unsigned long long int size) {
struct Base64Code ReturnData;
ReturnData.size = NULL;
ReturnData.data = NULL;
if (data == NULL || size == 0 || size % 4 != 0) {
return ReturnData;
}
ReturnData.data = (unsigned char*)malloc(size * 6 / 8 + 1);
if (ReturnData.data == NULL) {
return ReturnData;
}
char Base64Data[64]; unsigned long long int temp = 0; unsigned long long int i = 0;
for (temp = 0; temp < size * 6 / 8 + 1; temp++) {
ReturnData.data[temp] = 0;
}
unsigned long long int j = 0; Base64Data[62] = '+'; Base64Data[63] = '/';
for (i = 65; i < 91; i++) {
Base64Data[j] = i;
j++;
}
for (i = 97; i < 123; i++) {
Base64Data[j] = i;
j++;
}
for (i = 48; i < 58; i++) {
Base64Data[j] = i;
j++;
}
for (i = 0; i < size; i = i + 4) {
if (i == size - 4 && data[size - 1] == '=' && data[size - 2] == '=') {
for (j = 0; j < 64; j++) {
if (data[i] == Base64Data[j]) {
ReturnData.data[ReturnData.size] = ((unsigned char)(j << 2));
}
}
for (j = 0; j < 64; j++) {
if (data[i + 1] == Base64Data[j]) {
ReturnData.data[ReturnData.size] = ReturnData.data[ReturnData.size] + (j >> 4);
}
}
ReturnData.size = ReturnData.size + 1;
break;
}
else if (i == size - 4 && data[size - 1] == '=' && data[size - 2] != '=') {
for (j = 0; j < 64; j++) {
if (data[i] == Base64Data[j]) {
ReturnData.data[ReturnData.size] = ((unsigned char)(j << 2));
ReturnData.size = ReturnData.size + 1;
}
}
for (j = 0; j < 64; j++) {
if (data[i + 1] == Base64Data[j]) {
ReturnData.data[ReturnData.size - 1] = ReturnData.data[ReturnData.size - 1] + (j >> 4);
ReturnData.data[ReturnData.size] = (unsigned char)(j << 4);
ReturnData.size = ReturnData.size + 1;
}
}
for (j = 0; j < 64; j++) {
if (data[i + 2] == Base64Data[j]) {
ReturnData.data[ReturnData.size - 1] = ReturnData.data[ReturnData.size - 1] + (j >> 2);
ReturnData.data[ReturnData.size] = (unsigned char)(j << 6);
}
}
break;
}
for (j = 0; j < 64; j++) {
if (data[i] == Base64Data[j]) {
ReturnData.data[ReturnData.size] = ((unsigned char)(j << 2));
ReturnData.size = ReturnData.size + 1;
}
}
for (j = 0; j < 64; j++) {
if (data[i + 1] == Base64Data[j]) {
ReturnData.data[ReturnData.size - 1] = ReturnData.data[ReturnData.size - 1] + (j >> 4);
ReturnData.data[ReturnData.size] = (unsigned char)(j << 4);
ReturnData.size = ReturnData.size + 1;
}
}
for (j = 0; j < 64; j++) {
if (data[i + 2] == Base64Data[j]) {
ReturnData.data[ReturnData.size - 1] = ReturnData.data[ReturnData.size - 1] + (j >> 2);
ReturnData.data[ReturnData.size] = (unsigned char)(j << 6);
ReturnData.size = ReturnData.size + 1;
}
}
for (j = 0; j < 64; j++) {
if (data[i + 3] == Base64Data[j]) {
ReturnData.data[ReturnData.size - 1] = ReturnData.data[ReturnData.size - 1] + j;
}
}
}
return ReturnData;
}