Base64 ÀÎÄÚµù
ÃÑ ÆäÀÌÁö ¼ö : 3224

Àüü ÇÔ¼ö/¿ë¾î»çÀü
Facebook Joinc ±×·ì   Joinc QA »çÀÌÆ®
ÇöÀçÀ§Ä¡ : Code>C>base64



joinc´Â Firefox¿Í chrome¿¡¼­ Å×½ºÆ® Çß½À´Ï´Ù. IE¿¡¼­´Â Å×À̺íÀÌ ±úÁö°Å³ª À̹ÌÁö°¡ º¸ÀÌÁö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. ƯÈ÷ ±¸±Û DocsÀ̹ÌÁöÀÇ °æ¿ì ¿¢¹Úó¸®µÉ ¼ö ÀÖ½À´Ï´Ù.

¼³¸í

½ÃÁß¿¡ µ¹¾Æ´Ù´Ï´Â base64°ü·Ã ÇÔ¼ö¸¦ Â¥Áý±â ÇѰ̴ϴÙ. Ãâó´Â PHP3 ¿¡ µé¾î°£ Base64 Encode & Decode Source ¶ø´Ï´Ù.

¸ñÀûÀ¸·Î ÇÏ´Â ¹®ÀÚ¿­À» ÀÔ·ÂÇϸé base64·Î ÀÎÄÚµù°ú µðÄÚµùÀ» ½ÃÄÑÁÝ´Ï´Ù. base64´Â
À¥¿¡¼­ µ¥ÀÌÅ͸¦ Àü´Þ(Content-Transfer)Çϱâ À§ÇÑ ¸ñÀûÀ¸·Î »ç¿ëµË´Ï´Ù. »ç¶÷ÀÌ ÀÐÀ» ¼ö ¾ø´Â (¹ÙÀ̳ʸ®)µ¥ÀÌÅÍÀÇ °æ¿ì ³»¿ë°ú ÇüŰ¡ ¸Ú´ë·ÎÀÎ °æ¿ì°¡ ¸¹¾Æ¼­ ÀÌ »óÅ ±×´ë·Î´Â HTTPÇÁ·ÎÅäÄÝÀ» ÀÌ¿ëÇØ¼­ Àü´ÞÇϱⰡ ¾Ö¸Å¸ðÈ£Çѵ¥, À̰ÍÀ» Àϰü¼º ÀÖ´Â µ¥ÀÌÅÍ·Î ¹Ù²ãÁÝ´Ï´Ù. base64ÀÎÄÚµùÀ» ÇÒ°æ¿ì US-ASCII¿¡¼­ ÀÌ¿ëÇÏ´Â 65°³ÀÇ pritable ¹®ÀÚ·Î µ¥ÀÌÅ͸¦ À籸¼ºÇÕ´Ï´Ù.

ÀÎÄÚµù¿Í µðÄÚµù¿¡ »ç¿ëµÇ´Â ¾Ë°í¸®ÁòÀÌ °£´ÜÇÏ´Ù´Â ÀåÁ¡ÀÌ ÀÖÁö¸¸ µ¥ÀÌÅ͸¦ ÀÎÄÚµùÇÒ°æ¿ì ¿ø·¡ µ¥ÀÌÅÍ¿¡ ºñÇØ¼­ 33%Á¤µµ Å©±â°¡ Ä¿Áø´Ù´Â ´ÜÁ¡ÀÌ Á¸Àç ÇÕ´Ï´Ù.

<!> ÀÌ ÇÔ¼ö´Â ¿ÏÀüÇÏÁö ¾ÊÀº ¹öÁ¯ÀÔ´Ï´Ù. ³»ºÎ¿¡¼­ malloc()¸¦ ÇÑÈÄ free()ÇÏ´Â °úÁ¤ÀÌ ¾øÀ¸¹Ç·Î ¸Þ¸ð¸® ´©¼ö°¡ ¹ß»ýÇÒ ¼ö ÀÖ½À´Ï´Ù. ¾à°£ ¼öÁ¤À» ÇØ¾ß µÉ°Í °°Àºµ¥, ÀÏ´ÜÀº ±×³É ¿Ã¸³´Ï´Ù.

»ç¿ë¹æ¹ý

unsigned char *__base64_encode(const unsigned char *str,  
        int length, int *ret_length); 
unsigned char *__base64_decode(const unsigned char *str,  
        int length, int *ret_length); 
 
  1. str : ÀÎÄÚµù/µðÄÚµùÀ» À§ÇÑ µ¥ÀÌÅÍ
  2. length : ÀÎÄÚµù/µðÄÚµùÀ» À§ÇÑ µ¥ÀÌÅÍÀÇ Å©±â
  3. ret_length : ÀÎÄÚµù/µðÄÚµù°á°ú ³ª¿Â µ¥ÀÌÅÍÀÇ Å©±â

#include <encode.h> 
#include <stdio.h> 
 
int main() 
{ 
   unsigned char *str, *dst; 
   char *source = "hello world"; 
   int  size; 
 
   str = __base64_encode((unsigned char *)source, strlen(source), &size); 
   printf("%s : %d\n", str, size); 
   dst = __base64_decode(str, strlen(str), &size); 
   printf("%s : %d\n", dst, size); 
 
   free(str); 
   free(dst); 
 
} 
 

ÄÚµå

#include <stdlib.h> 
#include <string.h> 
 
// BASE64 
static char __base64_table[] ={ 
   'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 
   'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 
   'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 
   'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 
   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0' 
}; 
 
static char __base64_pad = '='; 
 
unsigned char *__base64_encode(const unsigned char *str, int length, int *ret_length) { 
   const unsigned char *current = str; 
   int i = 0; 
   unsigned char *result = (unsigned char *)malloc(((length + 3 - length % 3) * 4 / 3 + 1) * sizeof(char)); 
 
   while (length > 2) { /* keep going until we have less than 24 bits */ 
      result[i++] = __base64_table[current[0] >> 2]; 
      result[i++] = __base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)]; 
      result[i++] = __base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)]; 
      result[i++] = __base64_table[current[2] & 0x3f]; 
 
      current += 3; 
      length -= 3; /* we just handle 3 octets of data */ 
   } 
 
   /* now deal with the tail end of things */ 
   if (length != 0) { 
      result[i++] = __base64_table[current[0] >> 2]; 
      if (length > 1) { 
         result[i++] = __base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)]; 
         result[i++] = __base64_table[(current[1] & 0x0f) << 2]; 
         result[i++] = __base64_pad; 
      } 
      else { 
         result[i++] = __base64_table[(current[0] & 0x03) << 4]; 
         result[i++] = __base64_pad; 
         result[i++] = __base64_pad; 
      } 
   } 
   if(ret_length) { 
      *ret_length = i; 
   } 
   result[i] = '\0'; 
   return result; 
} 
 
/* as above, but backwards. :) */ 
unsigned char *__base64_decode(const unsigned char *str, int length, int *ret_length) { 
   const unsigned char *current = str; 
   int ch, i = 0, j = 0, k; 
   /* this sucks for threaded environments */ 
   static short reverse_table[256]; 
   static int table_built; 
   unsigned char *result; 
 
   if (++table_built == 1) { 
      char *chp; 
      for(ch = 0; ch < 256; ch++) { 
         chp = strchr(__base64_table, ch); 
         if(chp) { 
            reverse_table[ch] = chp - __base64_table; 
         } else { 
            reverse_table[ch] = -1; 
         } 
      } 
   } 
 
   result = (unsigned char *)malloc(length + 1); 
   if (result == NULL) { 
      return NULL; 
   } 
 
   /* run through the whole string, converting as we go */ 
   while ((ch = *current++) != '\0') { 
      if (ch == __base64_pad) break; 
 
      /* When Base64 gets POSTed, all pluses are interpreted as spaces. 
         This line changes them back.  It's not exactly the Base64 spec, 
         but it is completely compatible with it (the spec says that 
         spaces are invalid).  This will also save many people considerable 
         headache.  - Turadg Aleahmad <turadg@wise.berkeley.edu> 
      */ 
 
      if (ch == ' ') ch = '+'; 
 
      ch = reverse_table[ch]; 
      if (ch < 0) continue; 
 
      switch(i % 4) { 
      case 0: 
         result[j] = ch << 2; 
         break; 
      case 1: 
         result[j++] |= ch >> 4; 
         result[j] = (ch & 0x0f) << 4; 
         break; 
      case 2: 
         result[j++] |= ch >>2; 
         result[j] = (ch & 0x03) << 6; 
         break; 
      case 3: 
         result[j++] |= ch; 
         break; 
      } 
      i++; 
   } 
 
   k = j; 
   /* mop things up if we ended on a boundary */ 
   if (ch == __base64_pad) { 
      switch(i % 4) { 
      case 0: 
      case 1: 
         free(result); 
         return NULL; 
      case 2: 
         k++; 
      case 3: 
         result[k++] = 0; 
      } 
   } 
   if(ret_length) { 
      *ret_length = j; 
   } 
   result[k] = '\0'; 
   return result; 
} 
 

¶Ç´Ù¸¥ ¹öÁ¯

  • minzkn ¹öÁ¯
    • Ư¡: °íÁ¤Å©±â ¹öÆÛ¸¦ »ç¿ëÇÏÁö ¾Ê°í °¡º¯ÀûÀ¸·Î ÇÒ´çÇÏ¿© ³Ñ°ÜÁÜ.
    • ¿ø¹®¿¡ ´ëÇÏ¿© encode µÈ ¹®ÀÚ¿­ÀÇ Å©±â´Â Á¤È®È÷ ´ÙÀ½°ú °°Àº °ø½Ä¿¡ ÀÇÇØ¼­ Ä¿Áö°Å³ª ÀÛ¾ÆÁý´Ï´Ù. (¾Æ·¡ÀÇ °ø½ÄÀº Á¤¼ö¿¬»ê¹ýÀ¸·Î ¼Ò¼ýÁ¡Àº À߸°(¹ö¸²)´Ù´Â Á¶°Ç¿¡ ÀÇÇØ¼­ °è»êÇÏ°Ô Á¤¸®ÇغýÀ´Ï´Ù.) - minzkn
      1. ¿ø¹®À» encodeÇÏ¿´À»¶§ ¹®ÀÚ¿­ÀÇ ±æÀÌ = ((<¿ø¹®ÀÇ ±æÀÌ> + 2) / 3) * 4 = ((len + 2) / 3) << 2
      2. encodeµÈ ¹®ÀÚ¿­À» decodeÇÏ¿´À»¶§ ¹®ÀÚ¿­ÀÇ ±æÀÌ = ((<encodeµÈ ¹®ÀÚ¿­ÀÇ ±æÀÌ> + 3) / 4) + 3 = ((len + 3) >> 2) + 3
    • base64 ´Â 0~255 »çÀÌÀÇ ¹®ÀÚ°ªÀ» °¢°¢ 0~63ÀÇ 64´Ü°èÀÇ ¹®ÀÚ°ª¸¸À» »ç¿ëÇÏ¿© º¯È¯ÇÏ´Â °úÁ¤À» ¸»Çϸç 2±ÛÀÚ°¡ 3±ÛÀÚ·Î ´Ã¾î³³´Ï´Ù. À̰ÍÀÌ ÁÖ·Î »ç¿ëµÇ´Â ÀÌÀ¯´Â ¹®ÀÚ¿­ »çÀÌ¿¡ °ø¹éÀ» ³Ö¾î¼­´Â ¾ÈµÉ°æ¿ì¿Í ¸ÖƼ¹ÙÀÌÆ®¸¦ »ç¿ëÇÏÁö ¾Ê¾Æ¾ß ÇÒ °á¿ì¿¡ ¸¹ÀÌµé »ç¿ëÇÕ´Ï´Ù. °ø¹éÀ» ³ÖÁö ¾Ê¾Æ¾ß ÇÏ´Â °æ¿ì´Â ´ëºÎºÐ token ÀÌ °ø¹éÀ¸·Î ºÐ·ùµÉ¶§°¡ µÇ°ÚÁö¿ä. - minzkn
/* 
 Copyright (C) Information Equipment co.,LTD. 
 All rights reserved. 
 Code by JaeHyuk Cho <mailto:minzkn@infoeq.com> 
 CVSTAG="$Header: /usr/local/mutihost/joinc/modules/moniwiki/data/text/RCS/Code_2fC_2fbase64,v 1.2 2007/01/24 02:16:30 root Exp root $" 
 
 - Simple is best ! 
*/ 
 
#if !defined(__def_mzapi_source_base64_c__) 
#define __def_mzapi_source_base64_c__ "base64.c" 
 
#include <stdio.h> 
#include <stdlib.h> 
#include <memory.h> 
#include <malloc.h> 
 
#if !defined(__mzapi_peek_vector__) 
# define __mzapi_peek_vector__(m_cast,m_base,m_sign,m_offset)         ((m_cast)(((unsigned char *)(m_base)) m_sign (size_t)(m_offset))) 
#endif 
#if !defined(mzapi_peek_byte) 
# define mzapi_peek_byte(m_base,m_offset)                             (*__mzapi_peek_vector__(unsigned char *,m_base,+,m_offset)) 
#endif 
#if !defined(mzapi_poke_byte) 
# define mzapi_poke_byte(m_base,m_offset,m_value)                     (*__mzapi_peek_vector__(unsigned char *,m_base,+,m_offset)) = (unsigned char)(m_value) 
#endif 
 
static unsigned long (__mzapi_decode_base64__)(int s_character); 
char * (mzapi_encode_base64)(const char * s_string); 
char * (mzapi_decode_base64)(const char * s_string); 
int main(int s_argc, char **s_argv); 
 
static unsigned long (__mzapi_decode_base64__)(int s_character)  
{ 
      if((s_character) >= ((int)'a'))return((((unsigned long)(s_character)) - ((unsigned long)'a')) + 26lu);  
 else if((s_character) >= ((int)'A'))return(((unsigned long)(s_character)) - ((unsigned long)'A')); 
 else if((s_character) >= ((int)'0'))return((((unsigned long)(s_character)) - ((unsigned long)'0')) + 52lu); 
 else if((s_character) == ((int)'+'))return(62lu); 
 else if((s_character) == ((int)'/'))return(63lu); 
 return(0lu); 
} 
 
char * (mzapi_encode_base64)(const char * s_string) 
{ 
 static const unsigned char c_alpha_table[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}; 
 char * s_result; 
 size_t s_length = strlen(s_string), s_source_offset = (size_t)0, s_target_offset = (size_t)0; 
 unsigned long s_value; 
 int s_quad, s_trip; 
 s_result = (char *)malloc((((s_length + ((size_t)2)) / ((size_t)3)) << 2) + ((size_t)1)); 
 if(s_result == ((char *)0))return((char *)0); 
 while(s_source_offset < s_length) 
 { 
  s_value = ((unsigned long)(mzapi_peek_byte((void *)s_string, s_source_offset) & ((int)0xff))) << 8;  
  if((s_source_offset + ((size_t)1)) < s_length) 
  { 
   s_value |= (unsigned long)(mzapi_peek_byte((void *)s_string, s_source_offset + ((size_t)1)) & ((int)0xff));  
   s_trip = (int)1; 
  } 
  else s_trip = (int)0; 
  s_value <<= 8; 
  if((s_source_offset + ((size_t)2)) < s_length) 
  { 
   s_value |= (unsigned long)(mzapi_peek_byte((void *)s_string, s_source_offset + ((size_t)2)) & ((int)0xff));  
   s_quad = (int)1; 
  } 
  else s_quad = (int)0; 
  mzapi_poke_byte((void *)s_result, s_target_offset + ((size_t)3), (int)c_alpha_table[(s_quad == (int)1) ? (s_value & 0x3flu) : 64]); 
  s_value >>= 6; 
  mzapi_poke_byte((void *)s_result, s_target_offset + ((size_t)2), (int)c_alpha_table[(s_trip == (int)1) ? (s_value & 0x3flu) : 64]); 
  s_value >>= 6; 
  mzapi_poke_byte((void *)s_result, s_target_offset + ((size_t)1), (int)c_alpha_table[s_value & 0x3flu]); 
  s_value >>= 6; 
  mzapi_poke_byte((void *)s_result, s_target_offset, (int)c_alpha_table[s_value & 0x3flu]); 
  s_source_offset += (size_t)3, s_target_offset += (size_t)4; 
 } 
 mzapi_poke_byte((void *)s_result, s_target_offset, (int)'\0'); 
 return(s_result); 
} 
 
char * (mzapi_decode_base64)(const char * s_string) 
{ 
 char * s_result; 
 size_t s_length = strlen(s_string), s_source_offset = (size_t)0, s_target_offset = (size_t)0; 
 unsigned long s_value; 
 s_result = (char *)malloc((((s_length + ((size_t)3)) >> 2) * ((size_t)3)) + ((size_t)1)); 
 if(s_result == ((char *)0))return((char *)0); 
 while(s_source_offset < s_length) 
 { 
  s_value  = ((__mzapi_decode_base64__(mzapi_peek_byte((void *)s_string, s_source_offset)) & 0x3flu) << 18) | 
             ((__mzapi_decode_base64__(mzapi_peek_byte((void *)s_string, s_source_offset + ((size_t)1))) & 0x3flu) << 12) | 
             ((__mzapi_decode_base64__(mzapi_peek_byte((void *)s_string, s_source_offset + ((size_t)2))) & 0x3flu) << 6) | 
             (__mzapi_decode_base64__(mzapi_peek_byte((void *)s_string, s_source_offset + ((size_t)3))) & 0x3flu); 
  mzapi_poke_byte((void *)s_result, s_target_offset++, (int)((s_value >> 16) & 0xfflu)); 
  if(mzapi_peek_byte((void *)s_string, s_source_offset + ((size_t)2)) != ((int)'=')) 
  { 
   mzapi_poke_byte((void *)s_result, s_target_offset++, (int)((s_value >> 8) & 0xfflu)); 
   if(mzapi_peek_byte((void *)s_string, s_source_offset + ((size_t)3)) != ((int)'='))mzapi_poke_byte((void *)s_result, s_target_offset++, (int)(s_value & 0xfflu)); 
  }  
  s_source_offset += (size_t)4; 
 } 
 mzapi_poke_byte((void *)s_result, s_target_offset, (int)'\0'); 
 return(s_result); 
} 
 
int main(int s_argc, char **s_argv) 
{ 
 static char s_default[] = {"This is base64 test function - by minzkn"}; 
 char *s_this, *s_encode, *s_decode; 
 if(s_argc >= 2)s_this = (char *)(&s_argv[1][0]); 
 else s_this = s_default; 
 (void)fprintf(stdout, "original: \"%s\" (%d)\n", s_this, (int)strlen(s_this)); 
 s_encode = mzapi_encode_base64(s_this); 
 if(s_encode != ((char *)0)) 
 { 
  (void)fprintf(stdout, "encode  : \"%s\" (%d)\n", s_encode, (int)strlen(s_encode)); 
  s_decode = mzapi_decode_base64(s_encode); 
  if(s_decode != ((char *)0)) 
  { 
   (void)fprintf(stdout, "decode  : \"%s\" (%d)\n", s_decode, (int)strlen(s_decode)); 
   free((void *)s_decode); 
  } 
  free((void *)s_encode); 
 } 
 return(0); 
} 
 
#endif 
 
/* End of source */ 
 

º¯°æ»çÇ×

1. Ãâó ³»¿ë : PHP3 ¿¡ µé¾î°£ Base64 Encode & Decode Source
2. Çüº¯È¯(Visual C++ 6.0 SP6 ¿¡¼­ ¿¡·¯³²)
EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù.