一段把文件转为Base64编码和还原的代码

把下面的代码编译成一个可执行的控制台程序,加入名称为genf.exe

执行genf e xxxx.dat,加密文件

执行genf d xxxx.txt, 还原文件

做这个东西的主要目的是在这个Blog没有找到哪里可以上传文件

 

#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 = 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 = 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 = 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( 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;
 }
}

 

展开阅读全文

没有更多推荐了,返回首页