본문 바로가기

Native/C

base64

[code]

/**
* @file base64.h
* @author Robin Gareus <robin@gareus.org>
* @modifier cheol-dong choi <aucd29@gmail.com>
* @version 1.0
* @date June 15, 2010 20:55:53
* @section LICENSE
*
* Copyright 2007-2010 Robin Gareus <robin@gareus.org>
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* @section DESCRIPTION
*
*
* @section CHANGE_LOG
* - doxygen 형태로 변경 2010-12-13 (17:40:56)
*/


#ifndef __CD_BASE64_H__
#define __CD_BASE64_H__

#include <stdio.h>
#include <stdlib.h>


/**
* @fn static char b64_encode(unsigned char u)
* @brief Base64 encode one byte
*
* @param u
* @return
*/
static char b64_encode(unsigned char u)
{
    if(u < 26) return 'A'+u;
    if(u < 52) return 'a'+(u-26);
    if(u < 62) return '0'+(u-52);
    if(u == 62) return '+';
    return '/';
}


/**
* @fn static unsigned char b64_decode(char c)
* @brief Decode a single base64 character.
*
* @param c
* @return
*/
static unsigned char b64_decode(char c)
{
    if(c >= 'A' && c <= 'Z') return(c - 'A');
    if(c >= 'a' && c <= 'z') return(c - 'a' + 26);
    if(c >= '0' && c <= '9') return(c - '0' + 52);
    if(c == '+')             return 62;
    return 63;
}


/**
* @fn static int is_base64(char c)
* @brief Return TRUE if 'c' is a valid base64 character, otherwise FALSE
*
* @param c
* @return
*/
static int is_base64(char c)
{
    if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
        (c >= '0' && c <= '9') || (c == '+')             ||
        (c == '/')             || (c == '=')) {
            return 1;
    }
    return 0;
}


/**
* @fn static char *base64_encode(int size, const unsigned char *src)
* @brief Base64 encode and return size data in 'src'. The caller must free the
* returned string.
*
* @param size
* @param *src
* @return
*/
static char *base64_encode(int size, const unsigned char *src)
{
    int i;
    char *out, *p;

    if(!src) return NULL;
    if(!size) size= strlen((char *)src);
    out= (char*) calloc(sizeof(char), size*4/3+4);
    p= out;

    for(i=0; i<size; i+=3) {
        unsigned char b1=0, b2=0, b3=0, b4=0, b5=0, b6=0, b7=0;
        b1= src[i];
        if(i+1<size) b2= src[i+1];
        if(i+2<size) b3= src[i+2];

        b4= b1>>2;
        b5= ((b1&0x3)<<4)|(b2>>4);
        b6= ((b2&0xf)<<2)|(b3>>6);
        b7= b3&0x3f;

        *p++= b64_encode(b4);
        *p++= b64_encode(b5);

        if(i+1<size) *p++= b64_encode(b6);
        else *p++= '=';

        if(i+2<size) *p++= b64_encode(b7);
        else *p++= '=';
    }
    return out;
}


/**
* @fn static int base64_decode(unsigned char *dest, const char *src)
* @brief Decode the base64 encoded string 'src' into the memory pointed to by 'dest'.
*
* @param *dest
* @param *src
* @return
*/
static int base64_decode(unsigned char *dest, const char *src)
{
    if(src && *src) {
        unsigned char *p= dest;
        int k, l= strlen(src)+1;
        unsigned char *buf= (unsigned char*) calloc(sizeof(unsigned char), l);

        /* Ignore non base64 chars as per the POSIX standard */
        for(k=0, l=0; src[k]; k++) {
            if(is_base64(src[k])) {
                buf[l++]= src[k];
            }
        }

        for(k=0; k<l; k+=4) {
            char c1='A', c2='A', c3='A', c4='A';
            unsigned char b1=0, b2=0, b3=0, b4=0;
            c1= buf[k];

            if(k+1<l) c2= buf[k+1];
            if(k+2<l) c3= buf[k+2];
            if(k+3<l) c4= buf[k+3];

            b1= b64_decode(c1);
            b2= b64_decode(c2);
            b3= b64_decode(c3);
            b4= b64_decode(c4);

            *p++=((b1<<2)|(b2>>4) );

            if(c3 != '=') *p++=(((b2&0xf)<<4)|(b3>>2) );
            if(c4 != '=') *p++=(((b3&0x3)<<6)|b4 );
        }
        free(buf);
        dest[p-dest]='\0';
        return(p-dest);
    }
    return 0;
}

#endif
[/code]

'Native > C' 카테고리의 다른 글

iphone  (0) 2013.10.02
tt  (0) 2013.10.02
윤년  (0) 2013.10.02
daemon  (0) 2013.10.02
socket server sample code  (0) 2013.10.02