/* base64.cpp */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
//#include <conio.h>
#include <malloc.h>
#include "base64.h"
// US-ASCII テーブル
static char base64_table[] = {
'A','B','C','D','E','F','G','H',
'I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X',
'Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n',
'o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3',
'4','5','6','7','8','9','+','/'
// '='
};
#define IsBit(c) ((unsigned char)c) ? 0x01 : 0x00
inline
int gettableint(unsigned char str) {
for(int i = 0; i < 64; i++) {
if(str == base64_table[i]) break;
}
return i;
}
DWORD encode_base64(unsigned char* data, DWORD datalen, unsigned char* buffer) {
DWORD byte = 0;
unsigned char bit = 0x80;
unsigned char tmp;
DWORD size = 0, line = 0;
int i;
while(1) {
if(byte >= datalen) break;
*buffer = '\0';
for(i = 5; i >= 0; i--) {
tmp = IsBit(data[byte] & bit);
*buffer |= tmp ? (tmp << i) : *buffer;
bit >>= 1;
if(bit == 0x00) {
byte++;
if(byte >= datalen) break;
bit = 0x80;
}
}
*buffer = base64_table[*buffer];
buffer++;
size++;
line++;
// 改行
if(line >= 76) {
buffer[0] = '\r';
buffer[1] = '\n';
// buffer[2] = '\0';
buffer += 2;
size += 2;
line = 0;
}
}
tmp = (unsigned char)((size / 4 * 4 + 4) - size);
while(tmp--) {
*buffer = '=';
buffer++;
size++;
// 改行
if(line >= 76) {
buffer[0] = '\r';
buffer[1] = '\n';
buffer += 2;
size += 2;
line = 0;
}
}
*buffer = '\0';
return size;
}
DWORD decode_base64(unsigned char* data, DWORD datalen, unsigned char* buffer) {
int bit = 7;
unsigned char tmp;
unsigned char i, t;
DWORD size = 0;
DWORD byte=0;
*buffer = '\0';
while(1) {
if( (data[byte] == '=') || (data[byte] == '\0') || (byte > datalen) )
break;
if( (data[byte] == '\n') || (data[byte] == '\r') ) {
byte++;
continue;
}
tmp = gettableint(data[byte]);
if(tmp > 63) return 0;
for(i = 0x20; i != 0; i >>= 1) {
t = IsBit(tmp & i);
*buffer |= t ? t << bit : *buffer;
bit--;
if(bit < 0) {
buffer++;
*buffer = '\0';
size++;
bit = 7;
}
}
byte++;
}
return size;
}
void out_usage(void) {
printf(
"MIME base64 encode/decode\n"
"usage:\n"
" base64 [-e|d] inputfile outputfile\n"
);
}
int main(int argv, char* argc[]) {
FILE* finput;
FILE* foutput;
unsigned char* data;
unsigned char* buf;
DWORD datasize;
DWORD bufsize;
BOOL flag = TRUE;
if(argv < 4) {
out_usage();
return 0;
}
if(*argc[1] == '-') {
if(argc[1][1] == 'e')
flag = TRUE;
else if(argc[1][1] == 'd')
flag = FALSE;
else {
out_usage();
return 0;
}
}
finput = fopen(argc[2], "rb");
if(finput == NULL) {
printf("入力ファイル %s が開けません\n", argc[2]);
return 0;
}
fseek(finput, 0, SEEK_SET);
fseek(finput, 0, SEEK_END);
datasize = ftell(finput);
fseek(finput, 0, SEEK_SET);
data = (unsigned char*)malloc(datasize+1);
fread(data, 1, datasize, finput);
fclose(finput);
bufsize = datasize * 2 + 1024;
buf = (unsigned char*)malloc(bufsize);
if(flag)
bufsize = encode_base64(data, datasize, buf);
else
bufsize = decode_base64(data, datasize-1, buf);
free(data);
if(bufsize <= 0) {
free(buf);
printf("失敗しました\n");
return 0;
}
foutput = fopen(argc[3], "wb");
if(foutput == NULL) {
free(buf);
printf("出力ファイル %s が開けません\n", argc[3]);
return 0;
}
fwrite(buf, 1, bufsize, foutput);
free(buf);
return 0;
}
|