base64 인코딩 디코딩 예제 c 소스

본 글은 base64 encoder/decoder예제 c 소스 코드를 싣고 있다.

BASE64


BASE64는 일련의 데이터를 64종류"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"의 문자만을 이용하여 표현하도록 하는 부호화 방식이다. Base64는 인터넷 이메일 프로토콜이나 http url등에서 사용된다. 

부호화 과정은 아래와 같다.

문자 : Hello
Hex 코드 : 0x48 0x65 0x6c 0x6c 0x6f
8bits bin 코드: 01001000 01100101 01101100 01101100 01101111

8비트 단위의 문자를 6비트 단위로 분리한다.

6bits bin 코드 : 010010  000110  010101  101100  011011  000110  1111 00  ‘=’

6비트 2진 코드 값은 BASE64 코드 테이블의 인덱스이고 각 인덱스의 문자로 base64 부호화 한다. 마지막 모자라는 비트는 0으로 채우며, 4글자 단위로 부호화 하기 때문에 4글자가 안되면 ‘=’기호를 사용해 4글자를 맞춘다.

Base64 코드 : aGVsbG8=


Base64 Encoder source code


Base64 인코더 소스는 아래와 같다. 위의 부호화 예대로 text데이터를 받아 6bit 단위로 나누어 base64 코드 테이블에 맞춰 부호화를 진행한다.

static const char base64code_ascii[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

int text2base64_size(const char *text)
{
int len = strlen(text);
return ((len + 2) / 3 * 4);
}

int base64_encoder(char *in, int in_size, char *out, int out_size)
{
int i = 0;
int o = 0;

if (!in || !out) return 0;
if (text2base64_size(in) > out_size) return 0;

while (i < in_size - 2 && o+4 <= out_size)
{
out[o++] = base64code_ascii[(in[i] >> 2) & 0x3F];
out[o++] = base64code_ascii[((in[i] & 0x3) << 4) | ((int)(in[i + 1] & 0xF0) >> 4)];
out[o++] = base64code_ascii[((in[i + 1] & 0xF) << 2) | ((int)(in[i + 2] & 0xC0) >> 6)];
out[o++] = base64code_ascii[in[i + 2] & 0x3F];
i += 3;
}

if (i < in_size)
{
out[o++] = base64code_ascii[(in[i] >> 2) & 0x3F];
if (i == (in_size - 1))
{
out[o++] = base64code_ascii[((in[i] & 0x3) << 4)];
out[o++] = '='; // padding
}
else
{
out[o++] = base64code_ascii[((in[i] & 0x3) << 4) | ((int)(in[i + 1] & 0xF0) >> 4)];
out[o++] = base64code_ascii[((in[i + 1] & 0xF) << 2)];
}

out[o++] = '='; // padding
}

return o;
}

Base64 Decoder source


Base64 디코더 소스는 아래와 같다. base64 부호화 된 결과는 ascii 문자로 표현된다. ascii테이블에서 base64 코드 문자에 테이블의 인덱스 값을 넣어 복호화에 사용하였다. Base64에서 사용하지 않은 문자는 0xff값을 넣어 코드의 오류나 패딩 등을 검사하도록 했다. Base64 코드의 문자들은 각각이 6 bits 데이터이고, 위 부호화와 반대로 6bits 데이터들을 모아 8bits의 문자 코드로 복호화 한다.

static const unsigned char asciicode_base64code[256] =
{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
// 0x2b +, 0x2f /
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 62, 0xff, 0xff, 0xff, 63, 
// 0x30 : 0,1,2,...
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
// 0x40: @,A,B,C,...
0xff, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 
//0x50: P,Q,R,S,...
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0xff, 0xff, 0xff, 0xff, 0xff, 
// 0x60 : `,a,b,c,...
0xff, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 
// 0x70 : p,q,r,s,...
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};

아래 함수는 파라메터인 code 데이터의 유효한 base64코드의 길이를 반환하는 함수다. 데이터에 base64 문자가 아니거나 패딩 문자가 발견되면, 그전 데이터 길이를 반환한다.

int base64code_size(const char *code, int len)
{
int real_code_len = 0;
if (!code)
return 0;

while (real_code_len < len && asciicode_base64code[code[real_code_len]] != 0xff)
{
real_code_len++;
}

return real_code_len;
}

int base642text_size(const char *code,int len)
{
return ((base64code_size(code,len) + 3) / 4) * 3;
}

int base64_decoder(const char *in, int in_size, char *out, int out_size)
{
int i = 0;
int o = 0;
int real_code_len = 0;

if (!in || !out) return 0;
if (out_size < base642text_size(in, in_size)) return 0;

real_code_len = base64code_size(in, in_size);


while (i + 4 < real_code_len)
{
out[o++] = (char)(asciicode_base64code[in[i]] << 2 | asciicode_base64code[in[i+1]] >> 4);
out[o++] = (char)(asciicode_base64code[in[i + 1]] << 4 | asciicode_base64code[in[i + 2]] >> 2);
out[o++] = (char)(asciicode_base64code[in[i + 2]] << 6 | asciicode_base64code[in[i + 3]]);
i += 4;
}

if (real_code_len - i > 1)
{
out[o++] = (char)(asciicode_base64code[in[i]] << 2 | asciicode_base64code[in[i + 1]] >> 4);
}

if (real_code_len - i > 2)
{
out[o++] = (char)(asciicode_base64code[in[i + 1]] << 4 | asciicode_base64code[in[i + 2]] >> 2);
}

if (real_code_len - i > 3)
{
out[o++] = (char)(asciicode_base64code[in[i + 2]] << 6 | asciicode_base64code[in[i + 3]]);
}

return o;
}


인코더/디코더 테스트 코드

char *str = "hello base64 !";
char base64_code[128] = { 0, };
char text[128] = { 0, };
int ret = 0;

printf("%s\n", str);

ret = base64_encoder(str, strlen(str), base64_code, 128);
printf("base64 encoding : %s\n",base64_code);

ret = base64_decoder(base64_code, ret, text, 128);
printf("base64 decoding : %s\n",text);

 

댓글

이 블로그의 인기 게시물

바로 프로젝트 적용 가능한 FIR Filter (low/high/band pass filter )를 c나 python으로 만들기

간단한 cfar 알고리즘에 대해

쉽게 설명한 파티클 필터(particle filter) 동작 원리와 예제

windows에서 간단하게 크롬캐스트(Chromecast)를 통해 윈도우 화면 미러링 방법