아래 자료는 일자는 기억나지않지만 인터넷 어느곳에서 퍼왔던 자료입니다.
일부 수정하였으며 원글의 출처를 아시는 분은 알려주시면 감사 드리겠습니다.
※개념
2진 데이터를 아스키 텍스트로 변환하거나 그 반대로 변환하는 인코딩 방법. MIME에 의해 사용되는 방법으로,
4개의 7비트 아스키 문자로 표현되도록 데이터를 3바이트씩 4개의 6비트 단위로 나누어 표현한다.
메일에서 이미지, 오디오 파일을 보낼 때 이용하는 코딩으로 모든 플랫폼에서 안보이거나 깨지는 일이 생기지 않도록
공통으로 64개 아스키 코드를 이용하여 2진 데이터를 변환하기 위해 베이스 64를 이용한다.
따라서 베이스 64로 인코딩하면 크기가 33% 커진다.
아주 간단히 생각하고싶다면 바이너리 파일을 문자로 변환하여 보내고,
문자로 받으면 바이너리로 변환할수 있는 인코딩, 디코딩 방식 정도로만 생각하면 좋겠다.
64개를 표현하는데는 6비트가 필요하며 64개의 문자는 아래와 같다.
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
(대문자 A 가 0부터이고 마지막 = 는 Padding 문자)
사용하는 문자열의 앞뒤 순서는 상관없다. 다만, Encoding에 사용한 문자순서는 Decoding시 일치해야만 한다.
원칙은 Encoding 될 문자열을 6 비트로 끊어준다는 것과(위의 64개 문자로 표현하기 위해서) Encoding 될 문자열의 총 Bit 수를 3으로 나눈 나머지수만큼 ‘=’ 로 Padding 한다는 것이다.
#include<stdio.h>
#include<string.h>
#define BAD -1
#define DECODE64(c) (isascii(c) ? base64val[c] : BAD)
static const char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char base64val[128];
void main()
{
char in_password[20+1], out_password[100+1];
int i;
for (i=0; i<128; i++) {
base64val[i] = BAD;
}
for (i=0; i<64; i++) {
base64val[base64digits[i]] = i;
}
strcpy(in_password, "ABCDEFGHIJKL1234");
memset(out_password, 0x00, sizeof(out_password));
encode_base64(out_password, in_password, strlen(in_password));
printf("in=(%s), %d, out=(%s), %dn",
in_password, strlen(in_password), out_password, strlen(out_password));
exit(1);
}
encode_base64(unsigned char *out, unsigned char *in, int inlen)
{
for (; inlen >= 3; inlen -= 3) //3바이트를 6비트 단위로 끊어서 4바이트로 만듬.
{
*out++ = base64digits[in[0] >> 2]; //0번째 앞6자리
*out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)]; //0번째 뒤2자리 | 1번째 앞4자리
*out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; //1번째 뒤4자리 | 2번째 앞2자리
*out++ = base64digits[in[2] & 0x3f]; //2번째 뒤6자리
in += 3;
}
if (inlen > 0)
{
unsigned char fragment;
*out++ = base64digits[in[0] >> 2];
fragment = (in[0] << 4) & 0x30;
if (inlen > 1) fragment |= in[1] >> 4;
*out++ = base64digits[fragment];
*out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c];
*out++ = '=';
}
*out = '';
}
int decode_base64(unsigned char *out, unsigned char *in)
{
int len = 0;
unsigned char digit1, digit2, digit3, digit4;
if (in[0] == '+' && in[1] == ' ') in += 2;
if (*in == 'r') return(0);
do {
digit1 = in[0];
if (DECODE64(digit1) == BAD) return(-1);
digit2 = in[1];
if (DECODE64(digit2) == BAD) return(-1);
digit3 = in[2];
if (digit3 != '=' && DECODE64(digit3) == BAD) return(-1);
digit4 = in[3];
if (digit4 != '=' && DECODE64(digit4) == BAD) return(-1);
in += 4;
*out++ = (DECODE64(digit1) << 2) | (DECODE64(digit2) >> 4);
++len;
if (digit3 != '=')
{
*out++ = ((DECODE64(digit2) << 4) & 0xf0) | (DECODE64(digit3) >> 2);
++len;
if (digit4 != '=')
{
*out++ = ((DECODE64(digit3) << 6) & 0xc0) | DECODE64(digit4);
++len;
}
}
} while
(*in && *in != 'r' && digit4 != '=');
return (len);
}
댓글 남기기