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);
댓글
댓글 쓰기