// base64.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #define BASE64CHAR( ch ) ( (((ch)>='a')&&((ch)<='z')) || / (((ch)>='A')&&((ch)<='Z')) || / (((ch)>='0')&&((ch)<='9')) || / ((ch)=='+') || ((ch)=='/') || ((ch)=='=')) void Base64Encode( void* pSrc, int nLen, char* pObj ) {//pObj的长度需要(nLen+2)/3 * 4 +1 ,最后会填0 static char Base64EnTAB[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; int i; int count = nLen / 3; unsigned char *psSrc = (unsigned char*) pSrc; unsigned char *pszObj = (unsigned char *)pObj; unsigned char ch1,ch2,ch3; for( i = 0 ; i < count ; i ++ ) { ch1 = *psSrc ++; ch2 = *psSrc ++; ch3 = *psSrc ++; *pszObj ++ = ch1 >> 2; *pszObj ++ = ((ch1<<4)|(ch2>>4)) & 0x3f; *pszObj ++ = ((ch2<<2)|(ch3>>6)) & 0x3f; *pszObj ++ = ch3 & 0x3f; } count = nLen - (psSrc - (unsigned char *)pSrc); if( count == 1 || count == 2) { ch1 = *psSrc ++; if( count == 2 ) { ch2 = *psSrc ++; ch3 = 0; *pszObj ++ = ch1 >> 2; *pszObj ++ = ((ch1<<4)|(ch2>>4)) & 0x3f; *pszObj ++ = ((ch2<<2)|(ch3&0x03)) & 0x3f; } else { *pszObj ++ = ch1 >> 2; ch2 = 0; *pszObj ++ = ((ch1<<4)|(ch2>>4)) & 0x3f; *pszObj ++ = 64; } *pszObj ++ = 64; } count = pszObj - (unsigned char *)pObj; pszObj = (unsigned char *)pObj; for( i = 0 ; i < count ; i ++ ) { *pszObj = Base64EnTAB[ *pszObj ]; pszObj ++; //如果用下面的写法,在不同的编译器下,会有不同的结果 //*pszObj ++ = Base64EnTAB[ *pszObj ]; } *pszObj = '/0'; } int Base64Decode( char* pszSrc, void* pObj ) {//pObj需要的长度是strlen(pszSrc)/4*3 static char Base64DeTAB[] = {//0x2b begin 62,0, 0, 0, 63,//0x2? 52,53,54,55,56,57,58,59,60,61,0, 0, 0, 64,0, 0, //0x3? 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,//0x4? 15,16,17,18,19,20,21,22,23,24,25,0, 0, 0, 0, 0, //0x5? 0, 26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,//0x6? 41,42,43,44,45,46,47,48,49,50,51 //0x7? }; int i; int count = strlen( pszSrc ) / 4; char* psObj = (char*)pObj; for( i = 0 ; i < count ; i ++ ) { char ch1,ch2,ch3,ch4; ch1 = *pszSrc ++; ch2 = *pszSrc ++; ch3 = *pszSrc ++; ch4 = *pszSrc ++; if( BASE64CHAR(ch1) && BASE64CHAR(ch2) && BASE64CHAR(ch3) && BASE64CHAR(ch4)) { ch1 = Base64DeTAB[ch1 - 0x2b]; ch2 = Base64DeTAB[ch2 - 0x2b]; ch3 = Base64DeTAB[ch3 - 0x2b]; ch4 = Base64DeTAB[ch4 - 0x2b]; *psObj ++ = (ch1<<2)|(ch2>>4); *psObj ++ = (ch2<<4)|(ch3>>2); *psObj ++ = (ch3<<6)|ch4; } else return -1; } return 0; } int WriteFileContent( const char* pszFileName, char* buf, int len ) { FILE* fp = fopen( pszFileName, "wb" ); if( fp == NULL ) { fprintf( stderr, "open file %s for write fail/n", pszFileName ); return -1; } fwrite( buf, 1, len ,fp ); fclose( fp ); return 0; } char* ReadFileContent( const char* pszFileName, int* pFileLen ) { int filelen; char* buf = NULL; FILE* fp = fopen( pszFileName, "rb" ); if( fp == NULL ) { fprintf( stderr, "open file %s fail/n", pszFileName ); return NULL; } fseek( fp, 0, SEEK_END ); filelen = ftell( fp ); fseek( fp, 0, SEEK_SET ); if( filelen > 1024 * 1024 * 10 || filelen < 0 )//can not bigger than 10M { fprintf( stderr, "file %s is too large/n", pszFileName ); goto l_end; } buf = (char*)malloc( filelen + 1 ); if( buf == NULL ) { fprintf( stderr, "malloc fail/n"); goto l_end; } memset( buf, 0, filelen + 1 ); fread( buf, 1, filelen ,fp ); *pFileLen = filelen; return buf; l_end: if( buf != NULL ) free( buf ); fclose( fp ); return NULL; } char* FilterBase64Char( char* buf, int len, int* pLen ) { int i; int indexNew = 0; char* pBufNew =(char*) malloc( len+1 ); memset( pBufNew, 0, len + 1 ); for( i=0;i<len;i++ ) { if( BASE64CHAR(buf[i]) ) { pBufNew[indexNew++] = buf[i]; } } pBufNew[indexNew] = '/0'; *pLen = indexNew; return pBufNew; } int decodeFile( const char* pszFileName ) { char* buf,*bufB64,*bufPlain; char szFileNew[512]; int len; buf = ReadFileContent( pszFileName, &len ); if( buf == NULL ) return -1; bufB64 = FilterBase64Char( buf, len ,&len ); bufPlain =(char*) malloc( len + 1); memset( bufPlain, 0, len+1); if( Base64Decode( bufB64, bufPlain ) != 0 ) { fprintf( stderr, "Base64Decode fail/n"); return -1; } sprintf( szFileNew, "%s.rar", pszFileName ); if( WriteFileContent( szFileNew, bufPlain,strlen(bufB64)/4*3 ) != 0 ) return -1; printf("Write to file [%s](%d) OK/n", szFileNew,strlen(bufB64)/4*3 ); return 0; } int encodeFile( const char* pszFileName ) { char* buf,*bufB64; char szFileNew[512]; int i,len; int index = 0; buf = ReadFileContent( pszFileName, &len ); if( buf == NULL ) return -1; bufB64 =(char*) malloc( len*2+80 ); memset( bufB64, 0, len*2+80 ); for( i = 0 ; i < len ; i += 57 ) { char tmp[58]; memset( tmp, 0, sizeof(tmp)); memcpy( tmp, &buf[i], len-i>57?57:len-i); Base64Encode( tmp, 57, &bufB64[index] ); index += 76; bufB64[index++] = '/r'; bufB64[index++] = '/n'; } sprintf( szFileNew, "%s.txt", pszFileName ); if( WriteFileContent( szFileNew, bufB64,strlen(bufB64) ) != 0 ) return -1; printf("Write to file [%s](%d) OK/n", szFileNew,strlen(bufB64) ); return 0; } int main( int argc, char* argv[] ) { #if 0 if( argc < 3 ) { printf("Please input filename/n" ); return 0; } if( argv[1][0] == 'd' || argv[1][0] == 'D' ) { return decodeFile( argv[2] ); } else if ( argv[1][0] == 'e' || argv[1][0] == 'E' ) { return encodeFile( argv[2] ); } else { fprintf( stderr, "Command must be 'd' or 'e'/n" ); return -1; } #endif // encodeFile("d://3.jpg"); decodeFile( "d://1.txt" ); }