Base64エンコードとデコード
2010/04/25(日) 19:06 C言語このエントリーをはてなブックマークに追加

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));
}

名前:  非公開コメント   

  • TB-URL  http://efcl.info/adiary/034/tb/