// $Id$ // // Copyright (c) 2002-2006 greg landrum and rational discovery llc // // @@ All Rights Reserved @@ // #include #include #include #include "base64.h" // Encoding table from RFC 2045 // // Value Encoding Value Encoding Value Encoding Value Encoding // 0 A 17 R 34 i 51 z // 1 B 18 S 35 j 52 0 // 2 C 19 T 36 k 53 1 // 3 D 20 U 37 l 54 2 // 4 E 21 V 38 m 55 3 // 5 F 22 W 39 n 56 4 // 6 G 23 X 40 o 57 5 // 7 H 24 Y 41 p 58 6 // 8 I 25 Z 42 q 59 7 // 9 J 26 a 43 r 60 8 // 10 K 27 b 44 s 61 9 // 11 L 28 c 45 t 62 + // 12 M 29 d 46 u 63 / // 13 N 30 e 47 v // 14 O 31 f 48 w (pad) = // 15 P 32 g 49 x // 16 Q 33 h 50 y const int MaxLineLength=72; char *Base64Encode(const char *inText,const unsigned int inLen){ return Base64Encode((const unsigned char *)inText,inLen); } char *Base64Encode(const unsigned char *inText,const unsigned int inLen){ // Notes: // - whoever calls us is responsible for free'ing the result we return // - we cheat and don't worry about breaking lines static unsigned char transTable[64]={'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','+','/'}; char *res; int resSize; resSize = (4*inLen)/3; while(resSize % 4) resSize++; res = (char *)malloc(resSize+1); unsigned int i = 0; int pos = 0; while(i < inLen){ res[pos++]= transTable[inText[i]>>2]; if( i+1 < inLen){ res[pos++]= transTable[((inText[i]&3)<<4)|(inText[i+1]>>4)]; if(i+2 < inLen){ res[pos++] = transTable[((inText[i+1]&0xF)<<2)|(inText[i+2]>>6)]; res[pos++] = transTable[inText[i+2]&0x3F]; } else { // single padding res[pos++] = transTable[((inText[i+1]&0xF)<<2)]; res[pos++] = '='; } } else { // double padding res[pos++] = transTable[((inText[i]&3)<<4)]; res[pos++] = '='; res[pos++] = '='; } i += 3; } res[resSize] = 0; return res; } char *Base64Decode(const char *inText,unsigned int *size){ // Notes: // - whoever calls us is responsible for free'ing the result we return unsigned char transTable[256]; int inLen = strlen(inText); int i; // FIX: we don't really need to build this table here for(i= 0;i<255;i++){ transTable[i]= 0x80; } for(i='A';i<='Z';i++) transTable[i] = (unsigned char)i-'A'; for(i='a';i<='z';i++) transTable[i] = (unsigned char)i-'a'+26; for(i='0';i<='9';i++) transTable[i] = (unsigned char)i-'0'+52; transTable['+']=62; transTable['/']=63; int outLen = 3*inLen/4; char *res = (char *)calloc(outLen,sizeof(char)); int pos = 0; i = 0; // decode 4 bytes at a time unsigned char block[4]; int nInBlock=0; while(i < inLen){ unsigned char c = inText[i]; // above we set 0x80 as the junk marker in the translation table if ( !(transTable[c]&0x80) ){ block[nInBlock++] = transTable[c]; if( nInBlock == 4 ) { // finished a block res[pos++] = (block[0]<<2)|(block[1]>>4); res[pos++] = (block[1]<<4)|(block[2]>>2); res[pos++] = (block[2]<<6)|block[3]; nInBlock = 0; } } i++; } // okay, now there can be 2 or 3 chars remaining to be processed // (before the padding) if(nInBlock>1){ res[pos++] = (block[0]<<2)|(block[1]>>4); if(nInBlock > 2){ res[pos++] = (block[1]<<4)|(block[2]>>2); res[pos] = (block[2]<<6); } } *size = pos; return res; }