[C/CPP] Base64 Encoding & Decoding - WEBSHARE

[C/CPP] Base64 Encoding & Decoding

아래 자료는 일자는 기억나지않지만 인터넷 어느곳에서 퍼왔던 자료입니다.
일부 수정하였으며 원글의 출처를 아시는 분은 알려주시면 감사 드리겠습니다.

 

※개념

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) &amp; 0x30) | (in[1] >> 4)];    //0번째 뒤2자리 | 1번째 앞4자리
        *out++ = base64digits[((in[1] << 2) &amp; 0x3c) | (in[2] >> 6)];    //1번째 뒤4자리 | 2번째 앞2자리
        *out++ = base64digits[in[2] &amp; 0x3f];                            //2번째 뒤6자리
        in += 3;
    }

    if (inlen > 0)
    {
        unsigned char fragment;

        *out++ = base64digits[in[0] >> 2];
        fragment = (in[0] << 4) &amp; 0x30;

        if (inlen > 1)  fragment |= in[1] >> 4;

        *out++ = base64digits[fragment];
        *out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) &amp; 0x3c];
        *out++ = '=';
    }
    *out = '';
}

int decode_base64(unsigned char *out, unsigned char *in)
{
    int len = 0;
    unsigned char digit1, digit2, digit3, digit4;

    if (in[0] == '+' &amp;&amp; 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 != '=' &amp;&amp; DECODE64(digit3) == BAD)   return(-1); 

        digit4 = in[3];

        if (digit4 != '=' &amp;&amp; DECODE64(digit4) == BAD)   return(-1);

        in += 4;
        *out++ = (DECODE64(digit1) << 2) | (DECODE64(digit2) >> 4);
        ++len;

        if (digit3 != '=')
        {
            *out++ = ((DECODE64(digit2) << 4) &amp; 0xf0) | (DECODE64(digit3) >> 2);
            ++len;

            if (digit4 != '=')
            {
                *out++ = ((DECODE64(digit3) << 6) &amp; 0xc0) | DECODE64(digit4);
                ++len;
            }
        }

    } while 

    (*in &amp;&amp; *in != 'r' &amp;&amp; digit4 != '=');

    return (len);
}

게시됨

카테고리

작성자

태그:

댓글

“[C/CPP] Base64 Encoding & Decoding”에 대한 2개의 응답

  1. 박진규 아바타
    박진규

    감사합니다

댓글 남기기