C base64 decode

来源:互联网 发布:python编写界面 编辑:程序博客网 时间:2024/06/15 17:23
#include <stdio.h>

#define isbase64(a) (  ('A' <= (a) && (a) <= 'Z') \
                    || ('a' <= (a) && (a) <= 'z') \
                    || ('0' <= (a) && (a) <= '9') \
                    ||  (a) == '+' || (a) == '/'  )

char base64idx[128] = {
    '\377','\377','\377','\377','\377','\377','\377','\377',
    '\377','\377','\377','\377','\377','\377','\377','\377',
    '\377','\377','\377','\377','\377','\377','\377','\377',
    '\377','\377','\377','\377','\377','\377','\377','\377',
    '\377','\377','\377','\377','\377','\377','\377','\377',
    '\377','\377','\377',    62,'\377','\377','\377',    63,
        52,    53,    54,    55,    56,    57,    58,    59,
        60,    61,'\377','\377','\377','\377','\377','\377',
    '\377',     0,     1,     2,     3,     4,     5,     6,
         7,     8,     9,    10,    11,    12,    13,    14,
        15,    16,    17,    18,    19,    20,    21,    22,
        23,    24,    25,'\377','\377','\377','\377','\377',
    '\377',    26,    27,    28,    29,    30,    31,    32,
        33,    34,    35,    36,    37,    38,    39,    40,
        41,    42,    43,    44,    45,    46,    47,    48,
        49,    50,    51,'\377','\377','\377','\377','\377'
};

int decode_base64(const char* aIn, size_t aInLen, char* aOut,size_t aOutSize, size_t* aOutLen)
{

    size_t inLen = aInLen;
    char *out = aOut;
    size_t outSize = (inLen+3)/4*3;
    int isErr = 0, isEndSeen = 0;
    int b1, b2, b3, a[5],k;
    size_t inPos = 0, outPos = 0;
    register char c64Tag;

    if (!aIn || !aOut || !aOutLen)   return -1;

    if (aOutSize < outSize)        return -1;
    /* Get four input chars at a time and decode them. Ignore white space
     * chars (CR, LF, SP, HT). If '=' is encountered, terminate input. If
     * a char other than white space, base64 char, or '=' is encountered,
     * flag an input error, but otherwise ignore the char.
     */


    while (inPos < inLen) {
        a[1] = a[2] = a[3] = a[4] = 0;
                c64Tag = '\0';
                for ( k=1; k<=4; k++ ) {
            while (inPos < inLen) {
                        register char cMaskBit=0x01 ;
            a[k] = aIn[inPos++] & 0xFF;
            if (isbase64(a[k])) {
                            cMaskBit = cMaskBit<<k ;
                                c64Tag = c64Tag | cMaskBit ;
                break;
            }
            else if (a[k] == '=') {
                isEndSeen = 1;
                break;
            }
            else if (a[k] != '\r' && a[k] != '\n' && a[k] != ' ' && a[k] != '\t') {
                isErr++;
            }
            }
                } // for ( int k ...
        if ( c64Tag == 0x1E ) {  // a[1], a[2], a[3], a[4] base64 chars
            a[1] = base64idx[a[1]] & 0xFF;
            a[2] = base64idx[a[2]] & 0xFF;
            a[3] = base64idx[a[3]] & 0xFF;
            a[4] = base64idx[a[4]] & 0xFF;
            b1 = ((a[1] << 2) & 0xFC) | ((a[2] >> 4) & 0x03);
            b2 = ((a[2] << 4) & 0xF0) | ((a[3] >> 2) & 0x0F);
            b3 = ((a[3] << 6) & 0xC0) | ( a[4]       & 0x3F);
            out[outPos++] = (char)b1;
            out[outPos++] = (char)b2;
            out[outPos++] = (char)b3;
        }
        else if ( c64Tag == 0x0E && a[4]=='=' ) {    // a[1], a[2], a[3] base64 chars and a[4] is '='
            a[1] = base64idx[a[1]] & 0xFF;
            a[2] = base64idx[a[2]] & 0xFF;
            a[3] = base64idx[a[3]] & 0xFF;
            b1 = ((a[1] << 2) & 0xFC) | ((a[2] >> 4) & 0x03);
            b2 = ((a[2] << 4) & 0xF0) | ((a[3] >> 2) & 0x0F);
            out[outPos++] = (char)b1;
            out[outPos++] = (char)b2;
            break;
        }
        else if ( c64Tag == 0x06 && a[3]=='=' && a[4]=='=' ) {
            a[1] = base64idx[a[1]] & 0xFF;
            a[2] = base64idx[a[2]] & 0xFF;
            b1 = ((a[1] << 2) & 0xFC) | ((a[2] >> 4) & 0x03);
            out[outPos++] = (char)b1;
            break;
        }
        else {
            break;
        }
        if (isEndSeen) {
            break;
        }
    } /* end while loop */
    *aOutLen = outPos;
    return (isErr) ? isErr : 0;
}

int main()
{
    int s = 10;
    char * dest = (char*)malloc(100);
    int e = decode_base64("PHA+44Oz44OAMTIzPC9wPg==",24,dest, 100, &s);

    printf("%d=%s\r\n",e,dest);
    return 0;
}


原创粉丝点击