반응형

 

컴퓨터 분야에서 쓰이는 Base 64 (베이스 육십사)란 8비트 이진 데이터(예를 들어 실행 파일이나, ZIP 파일 등)를 문자 코드에 영향을 받지 않는 공통 ASCII 영역의 문자들로만 이루어진 일련의 문자열로 바꾸는 인코딩 방식을 가리키는 개념이다. 원래 Base 64를 글자 그대로 번역하여 보면 64진법이란 뜻이다. 특별히 64진법이 컴퓨터에서 흥미로운 것은, 64가 2의 제곱수(64 = 26)이며, 2의 제곱수들에 기반한 진법들 중에서 화면에 표시되는 ASCII 문자들을 써서 표현할 수 있는 가장 큰 진법이기 때문이다. 즉, 다음 제곱수인 128진법에는 128개의 기호가 필요한데 화면에 표시되는 ASCII 문자들은 128개가 되지 않는다. 그런 까닭에 이 인코딩은 전자 메일을 통한 이진 데이터 전송 등에 많이 쓰이고 있다.  (위키백과 참조)

 

소스 파일은 이 페이지의 하단에서 다운로드할 수 있습니다.


 

 

BASE64 encoding/decoding 구현 함수의 header file
(base64.h)

#ifndef __BASE64_H__
#define __BASE64_H__

/* ==================================================================
  BASE64_encode
    주어진 문자열을 base64로 encoding한다.(= padding추가)
  parameter
    dest : base64 encoding한 데이터를 저장함
    src : base64 encoding할 데이터
    src_len : encoding할 데이터의 길이
  return
    0 이상 : encoding된 데이터의 길이(0 또는 4의 배수)
    -1 이하 : 오류
       -1 : 문자열의 길이가 -값으로 설정됨
================================================================== */
int BASE64_encode(char* dest, int dest_size, const unsigned char* src, size_t src_len);

/* ==================================================================
  BASE64_decode
    Base64로 encoding된 데이터를 decoding한다.
  parameter
    dest : decoding 결과를 저장할 buffer
    src : decoding할 데이터(base64 encoding된 데이터)
    src_len : decoding할 데이터의 길이(4의 배수이어야 함)
  return
    0 이상 : decoding된 데이터의 길이
    -1 : decoding할 data의 길이가 4의 배수가 아님
    -2 : decoding data가 base64 규칙이 아님
================================================================== */
int BASE64_decode(unsigned char* dest, int dest_size, const char* src, size_t src_len);

#endif

 


 

base64 encoding/decoding함수의 구현

(base64.c)

#include <string.h>

static const char BASE64_CHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char BASE64_PAD_CHAR = '=';
static const int  BASE64_PAD_CHAR_CODE = 64;

/* ==================================================================
  BASE64_index
    Base64 encoding된 문자가 BASE64 code상 몇번째에 위치하는 지를 return 한다.
  parameter
    ch : base64코드표의 위치를 얻으려는 문자(A~Z,a~z,0~9,+,/)
  return
    0 이상 : BASE64 문자표 상의 위치
    -1 : BASE64 encoding 문자표가 아님
================================================================== */
static int BASE64_index(char ch)
{
    if('A' <= ch && ch <= 'Z') {
        return ch - 'A';
    } else if('a' <= ch && ch <= 'z') {
        return ch - 'a' + 26;
    } else if('0' <= ch && ch <= '9') {
        return ch - '0' + 52;
    } else if(ch == '+') {
        return 62;
    } else if(ch == '/') {
        return 63;
    } else if(ch == BASE64_PAD_CHAR) {
        return BASE64_PAD_CHAR_CODE;
    } else {
        return -1;
    }
}

/* ==================================================================
  BASE64_block_encode
    3바이트 이하의 문자열을 base64로 encoding하여 4바이트로 변환한다. (= padding추가)
  parameter
    dest : base64 encoding한 데이터를 저장함
    src : base64 encoding할 데이터
    src_len : encoding할 데이터의 길이
  return
    0 이상 : encoding된 데이터의 길이(0 또는 4)
    -1 이하 :
    -1 : 문자열의 길이가 -값으로 설정됨
================================================================== */
static int BASE64_block_encode(unsigned char *dest, const unsigned char *src, int src_len)
{
    memset(dest, '=', 4);

    if(src_len < 0) {
        return -1;
    } else if(src_len == 0) {
        return 0;
    }
    dest[0] = BASE64_CHARS[src[0] >> 2];
    if(src_len == 1) {
        dest[1] = BASE64_CHARS[(src[0] & 0x03) << 4];
        return 4;
    }
    dest[1] = BASE64_CHARS[((src[0] & 0x03) << 4) | (src[1] >> 4)];
    if(src_len == 2) {
        dest[2] = BASE64_CHARS[(src[1] & 0x0f) << 2];
        return 4;
    }
    dest[2] = BASE64_CHARS[((src[1] & 0x0f) << 2) | (src[2] >> 6)];
    dest[3] = BASE64_CHARS[src[2] & 0x3f];

    return 4;
}

/* ==================================================================
  BASE64_encode
    주어진 문자열을 base64로 encoding한다.(= padding추가)
  parameter
    dest : base64 encoding한 데이터를 저장함
    src : base64 encoding할 데이터
    src_len : encoding할 데이터의 길이
  return
    0 이상 : encoding된 데이터의 길이(0 또는 4의 배수)
    -1 이하 : 오류
       -1 : 문자열의 길이가 -값으로 설정됨
================================================================== */
int BASE64_encode(char* dest, int dest_size, const unsigned char* src, size_t src_len)
{
    int idx1, idx2;
    int ret = 0;
    int rslt_len = 0;
   
    for(idx1 = 0, idx2 = 0; idx1 < src_len; idx1 += 3, idx2 += 4) {
        ret = BASE64_block_encode(&dest[idx2], &src[idx1], src_len - idx1 >= 3 ? 3 : src_len - idx1);
        if(ret < 0) {
            return ret;
        } else {
            rslt_len += ret;
        }
    }
    return rslt_len;
}


/* ==================================================================
  BASE64_block_decode
    Base64로 된 4바이트의 데이터를 decoding한다
  parameter
    dest : decoding 결과를 저장할 buffer
    src : decoding할 데이터(base64 encoding된 데이터)
    src_len : decoding할 데이터의 길이(항상 4)
  return
    0 이상 : decoding된 데이터의 길이
    -1 이하 : 오류
       -1 : decoding할 data의 길이가 4의 배수가 아님
       -2 : decoding data가 base64 규칙이 아님
================================================================== */
static int BASE64_block_decode(unsigned char *dest, const unsigned char *src, int src_len)
{
    int ch[4], idx;

    if(src_len == 0) {
        return 0;
    } else if(src_len != 4) {
        return -1;
    }

    for(idx = 0; idx < src_len; idx++) {
        if((ch[idx] = BASE64_index(src[idx])) < 0) {
            return -2;
        }
    }
    if(ch[0] == BASE64_PAD_CHAR_CODE || ch[1] == BASE64_PAD_CHAR_CODE) {
        return -2;
    }
   
    dest[0] = (ch[0] << 2) | (ch[1] >> 4);
    if(ch[2] == BASE64_PAD_CHAR_CODE) {
        return 1;
    }
    dest[1] = ((ch[1] & 0x0f) << 4) | (ch[2] >> 2);
    if(ch[3] == BASE64_PAD_CHAR_CODE) {
        return 2;
    }
    dest[2] = ((ch[2] & 0x03) << 6) | ch[3];
    return 3;
}

/* ==================================================================
  BASE64_decode
    Base64로 encoding된 데이터를 decoding한다.
  parameter
    dest : decoding 결과를 저장할 buffer
    src : decoding할 데이터(base64 encoding된 데이터)
    src_len : decoding할 데이터의 길이(4의 배수이어야 함)
  return
    0 이상 : decoding된 데이터의 길이
    -1 : decoding할 data의 길이가 4의 배수가 아님
    -2 : decoding data가 base64 규칙이 아님
================================================================== */
int BASE64_decode(unsigned char* dest, int dest_size, const char* src, size_t src_len)
{
    int idx1, idx2;
    int ret = 0;
    int rslt_len = 0;

    if(src_len % 4 != 0) {
        return -1;
    }
    for(idx1 = 0, idx2 = 0; idx1 < src_len; idx1 += 4, idx2 += 3) {
        ret = BASE64_block_decode(&dest[idx2], &src[idx1], src_len - idx1 >= 4 ? 4 : src_len - idx1);
        if(ret < 0) {
            return ret;
        } else {
            rslt_len += ret;
        }
    }
    return rslt_len;
}

 


 

base64 encoding/decoding 함수 호출 sample 소스

#include <stdio.h>
#include <string.h>
#include <base64.h>

int main(int argc, char **argv)
{
    char buffer[100] = "가나다123456";
    char base64[100];
    char decode[100];
    int ret_size;
  
    memset(base64, 0x00, sizeof(base64));
    memset(decode, 0x00, sizeof(decode));
   
    printf("[%s] : [%d]bytes encoding....\n", buffer, strlen(buffer));
    ret_size = BASE64_encode(base64, 1000, buffer, strlen(buffer));
    printf("ret size: [%d]\n", ret_size);
    printf("base64: [%s]\n", base64);
   
    ret_size = BASE64_decode(decode, 1024, base64, strlen(base64));
    printf("ret size: [%d]\n", ret_size);
    printf("decode: [%s]\n", decode);
   
    return 0;
}

 

 


 

파일 다운로드

base64.h
0.00MB
base64.c
0.01MB
base64_example.c
0.00MB

반응형
블로그 이미지

자연&사람

행복한 개발자 programmer since 1995.

,