아래 자료는 일자는 기억나지않지만 인터넷 어느곳에서 퍼왔던 자료입니다.
일부 수정하였으며 원글의 출처를 아시는 분은 알려주시면 감사 드리겠습니다.
※개념
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); }
댓글 남기기