#include <STDIO.H>
#include <MALLOC.H>
#include <TCHAR.H>

static const char Base64_EM[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; //!< Base64 인코드 테이블
static   char Base64_DM[256] = {0,};                 //!< Base64 디코드 테이블


/*!
\brief  
 Base64 초기화 함수
 제공되는 다른 함수를 사용하기 이전에 선행 호출
\see  
*/
void base64_Init()
{
 for(int i = 0; i<256; i++)
  Base64_DM[i] = -1;

 for(int i = 0; i<64; i++)
  Base64_DM[Base64_EM[i]] = i;

 return;
}

/*!
\brief
 Base64 Encode 함수
 메모리의 내용을 문자열로 변환하여 주는 함수

\param[in] pInBuf    문자열로 바꿀 메모리의 포인터
\param[in] ulSize   문자열로 바꿀 메모리의 크기
\param[out] ppOutBuf   변환된 문자열을 받을 메모리 포인터이며, 내부에서 할당하여 반환하므로 사용이 끝나면 free 하여야 한다.

\return  할당된 ppOutBuf 메모리의 크기
\see  
*/
int base64_Encode(unsigned char *pInBuf, unsigned long ulSize, unsigned char **ppOutBuf)
{
 unsigned char input[3]  = {0,};
 unsigned char output[4] = {0,};

 unsigned long ulOutbufSize = 0;

 unsigned long ulOctaPosition = 0;
 unsigned long ulOctaSplit  = 0;
 unsigned long ulHexaSplit  = 0;

 unsigned char *pOctaBit  = 0;
 unsigned char *pOctaBit_endof = 0;

 pOctaBit_endof = pInBuf + ulSize - 1;
 ulOutbufSize = (4 * (ulSize / 3)) + (ulSize % 3? 4 : 0) + 1;

 (*ppOutBuf)  = (unsigned char*)malloc(ulOutbufSize);

 for  (pOctaBit = pInBuf;pOctaBit <= pOctaBit_endof; ulOctaSplit++, pOctaBit++) {
  ulOctaPosition   = ulOctaSplit % 3;
  input[ulOctaPosition] = *pOctaBit;

  if (ulOctaPosition == 2 || pOctaBit == pOctaBit_endof) {
   output[0] = ((input[0] & 0xFC) >> 2);
   output[1] = ((input[0] & 0x3) << 4) | ((input[1] & 0xF0) >> 4);
   output[2] = ((input[1] & 0xF) << 2) | ((input[2] & 0xC0) >> 6);
   output[3] = (input[2] & 0x3F);

   (*ppOutBuf)[ulHexaSplit++] = Base64_EM[output[0]];
   (*ppOutBuf)[ulHexaSplit++] = Base64_EM[output[1]];
   (*ppOutBuf)[ulHexaSplit++] = ulOctaPosition == 0? '_' : Base64_EM[output[2]];
   (*ppOutBuf)[ulHexaSplit++] = ulOctaPosition <  2? '_' : Base64_EM[output[3]];

   input[0] = input[1] = input[2] = 0;
  }
 }

 (*ppOutBuf)[ulHexaSplit] = '\0';

 return ulOutbufSize;
}

/*!
\brief
 Base64 Decode 함수
 문자열을 원본 데이터로 변환하여 주는 함수

\param[in] pInBuf    변환할 문자열
\param[in] ulSize   복원할 사이즈, Encode시의 Return 값과 같다.
\param[out] pOutBuf   복원 내용을 받을 메모리 포인터

\return  복원된 데이터의 사이즈
\see base64_Encode 
*/
int base64_Decode(unsigned char *pInBuf, unsigned long ulSize, unsigned char *pOutBuf)
{
 unsigned long ulOctaPosition = 0;
 unsigned long ulHexaPosition = 0;
 
 unsigned char* pOctaBit  = 0;
 unsigned char cOctaBit  = 0;
 char   cHexaBit  = 0;
 char   cHexaBit_prev = 0;

 for ( pOctaBit = pInBuf; *pOctaBit != '\0'; ++pOctaBit ) {
  cHexaBit = Base64_DM[(int) *pOctaBit];

  if ( cHexaBit != -1 ) {
   switch ( ulHexaPosition ) {
    case 0:
     ++ulHexaPosition;
     break;
    case 1:
     cOctaBit = ( ( cHexaBit_prev << 2 ) | ( ( cHexaBit & 0x30 ) >> 4 ) );
     if ( ulOctaPosition < ulSize )
      pOutBuf[ulOctaPosition++] = cOctaBit;
     ++ulHexaPosition;
     break;
    case 2:
     cOctaBit = ( ( ( cHexaBit_prev & 0xf ) << 4 ) | ( ( cHexaBit & 0x3c ) >> 2 ) );
     if ( ulOctaPosition < ulSize )
      pOutBuf[ulOctaPosition++] = cOctaBit;
     ++ulHexaPosition;
     break;
    case 3:
     cOctaBit = ( ( ( cHexaBit_prev & 0x03 ) << 6 ) | cHexaBit );
     if ( ulOctaPosition < ulSize )
      pOutBuf[ulOctaPosition++] = cOctaBit;
     ulHexaPosition = 0;
     break;
   }
   cHexaBit_prev = cHexaBit;
  }
 }

 return ulOctaPosition;

}

Posted by 모과이IT
,