Base64エンコードとデコード
codetovalueは結局使ってない。
#include <stdio.h>
#include <string.h>
#include <malloc.h>
/* BASE64変換テーブル */
const static char BASE64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/=";
/* エンコード */
unsigned char* base64Encode(unsigned char *source){
unsigned char* result = NULL;
unsigned char buf1,buf2,buf3;
unsigned char ind1,ind2,ind3,ind4;
int i,j;
int size = sizeof(source[0])*strlen(source);
/* 結果領域 */
result = calloc(sizeof(char), (size*2)+1);
/*
3バイト(24ビット)ごとにデータを、6ビットごと分割
*/
for( i = 0, j = 0 ; i < size ; i += 3,j += 4){
/* 文字コード値取得 */
buf1 = (i < size - 0) ? *(source + i + 0) : '\0';
buf2 = (i < size - 1) ? *(source + i + 1) : '\0';
buf3 = (i < size - 2) ? *(source + i + 2) : '\0';
//printf("文字コード(16進数) %d : %d : %d \n", buf1,buf2,buf3);
/* 3文字=>4文字へ分解
つまり2進表現に直して、6bitずつに分割
*/
ind1 = (buf1 >> 2);// 2bit右シフト
ind2 = (buf1 & 0x03) << 4 | (buf2 >> 4);// 0x3f は2進数で111111
ind3 = (buf2 & 0x0f) << 2 | (buf3 >> 6);// 0x0f は2進数で 1111
ind4 = (buf3 & 0x3f);
//printf("4分割 %d : %d : %d : %d\n", ind1,ind2,ind3,ind4);
/* エンコード
変換テーブルに従いキャラクター文字に変換
*/
*(result + j + 0) = BASE64[ind1];
*(result + j + 1) = BASE64[ind2];
*(result + j + 2) = ( i < size - 1 ) ? BASE64[ind3] : '=';// 端数は=に
*(result + j + 3) = ( i < size - 2 ) ? BASE64[ind4] : '=';
}
return(result);
}
/* *(source + i + 0) */
unsigned char codetovalue(unsigned char c)
{
printf("%c @",c);
if( (c >= (unsigned char)'A') && (c <= (unsigned char)'Z') ) {
return (long)(c - (unsigned char)'A');
}
else if( (c >= (unsigned char)'a') && (c <= (unsigned char)'z') ) {
return ((long)(c - (unsigned char)'a') +26);
}
else if( (c >= (unsigned char)'0') && (c <= (unsigned char)'9') ) {
return ((long)(c - (unsigned char)'0') +52);
}
else if( (unsigned char)'+' == c ) {
return (long)62;
}
else if( (unsigned char)'/' == c ) {
return (long)63;
}
else if( (unsigned char)'=' == c ) {
return (long)0;
}
else {
return -1;
}
}
/* デコード */
unsigned char* base64Decode(unsigned char *source){
unsigned char* result = NULL;
unsigned char ind1,ind2,ind3,ind4;
int i,j;
int size = sizeof(source[0])*strlen(source);
/* 結果領域 */
result = calloc(sizeof(char), size + 3);
for( i = 0, j = 0 ; i < size ; i += 4 , j += 3){
/* 文字コード値取得 */
ind1 = *(source + i + 0) == '=' ? 0 : strchr(BASE64, *(source + i + 0)) - BASE64;// codetovalueと同じ
ind2 = *(source + i + 1) == '=' ? 0 : strchr(BASE64, *(source + i + 1)) - BASE64;
ind3 = *(source + i + 2) == '=' ? 0 : strchr(BASE64, *(source + i + 2)) - BASE64;
ind4 = *(source + i + 3) == '=' ? 0 : strchr(BASE64, *(source + i + 3)) - BASE64;
// printf("4分割 %d : %d : %d : %d\n", ind1,ind2,ind3,ind4);
/* デコード */
*(result + j + 0) = (unsigned char)( (ind1 & 0x3f) << 2 | (ind2 & 0x30) >> 4 );
*(result + j + 1) = (unsigned char)( (ind2 & 0x0f) << 4 | (ind3 & 0x3c) >> 2 );
*(result + j + 2) = (unsigned char)( (ind3 & 0x03) << 6 | (ind4 & 0x3f) >> 0 );
}
return(result);
}
main()
{
char *src = "Hello World";
char *decoded = base64Encode(src);
printf("encode : %s\n", decoded);
printf("decode : %s\n", base64Decode(decoded));
}
コメント(0件)
- TB-URL http://efcl.info/adiary/034/tb/