/
* Program:
* base64 encode & decode
* Author:
* brant-ruan * Date: * 2016-02-29 * Usage:
* Encode:
* ./base64 -e src-file dst-file
* Decode:
* ./base64 -d src-file dst-file
* P.S.
* To use this tool correctly, you must ensure that your src-file is valid.
Update:
* 2016-03-07
* I choose stdout as output file and stdin as input by default to abide by Linux
* philosophy.(So you can use pipe instruction)
/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OK 0
#define ERROR -1
#define CHART_SIZE 64
typedef int Status;
// standard base64 encoding chart
char std_chart[CHART_SIZE+1] = {
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/"
};
Status Encode();
Status Decode();
void MsgPrt(char *msg);
int main(int argc, char **argv)
{
if(argc != 2){
MsgPrt(argv[0]);
}
else if(strcmp("-e", argv[1]) == 0){
Encode();
}
else if(strcmp("-d", argv[1]) == 0){
Decode();
}
else{
MsgPrt(argv[0]);
}
return OK;
}
/* print error when arguments error happen */
void MsgPrt(char *msg)
{
printf("Usage:\n");
printf("\tEncode: %s -e src-file des-file\n", msg);
printf("\tDecode: %s -d src-file des-file\n", msg);
}
/* base64 encoding */
Status Encode()
{
char in[3];
char tempc;
// Encoding process
int i = 0;
while((tempc = fgetc(stdin)) != EOF){
in[i++] = tempc;
if(i == 3){
// char 1
tempc = (in[0] >> 2) & 0x3f;
fputc(std_chart[tempc], stdout);
// char 2
tempc = ((in[0] << 4) & 0x30) | ((in[1] >> 4) & 0x0f);
fputc(std_chart[tempc], stdout);
// char 3
tempc = ((in[1] << 2) & 0x3c) | ((in[2] >> 6) & 0x03);
fputc(std_chart[tempc], stdout);
// char 4
tempc = in[2] & 0x3f;
fputc(std_chart[tempc], stdout);
// initialize 'i'
i = 0;
}
}
// if the file's size is not times of 3:
if(i != 0){
tempc = (in[0] >> 2) & 0x3f;
fputc(std_chart[tempc], stdout);
}
if(i == 1){ // if there is 1 byte rest
tempc = (in[0] << 4) & 0x30;
fputc(std_chart[tempc], stdout);
fputc('=', stdout);
fputc('=', stdout);
}
if(i == 2){ // if there are 2 bytes rest
tempc = ((in[0] << 4) & 0x30) | ((in[1] >> 4) & 0x0f);
fputc(std_chart[tempc], stdout);
tempc = (in[1] << 2) & 0x3c;
fputc(std_chart[tempc], stdout);
fputc('=', stdout);
}
fclose(stdin);
return OK;
}
/* return the index of char in std_chart */
char ReIndex(char tempc)
{
int i;
for(i = 0; (i<CHART_SIZE) && (std_chart[i] != tempc); i++)
;
if(i < CHART_SIZE)
return i;
return ERROR;
}
/* base64 decoding */
Status Decode()
{
char in[4];
char tempc;
// Decoding process
int i = 0;
while((tempc = fgetc(stdin)) != EOF){
if(tempc == '=') // go to Extra situation
break;
in[i++] = ReIndex(tempc);
if(i == 4){
// char 1
tempc = (in[0] << 2) | ((in[1] >> 4) & 0x03);
fputc(tempc, stdout);
// char 2
tempc = (in[1] << 4) | (in[2] >> 2);
fputc(tempc, stdout);
// char 3
tempc = (in[2] << 6) | (in[3] & 0x3f);
fputc(tempc, stdout);
i = 0;
}
}
if(tempc == '='){ // Extra situation
tempc = (in[0] << 2) | ((in[1] >> 4) & 0x03);
fputc(tempc, stdout);
if(i == 3){
tempc = (in[1] << 4) | (in[2] >> 2);
fputc(tempc, stdout);
}
}
return OK;
}