Base64 编解码C语言实现

#include <stdio.h>
#include <Windows.h>

const char base[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
char* base64_encode(const char* data, int data_len);
char *base64_decode(const char* data, int data_len);

static char find_pos(char ch);
int main(int argc, char* argv[])
{    
 char *t = "那个abcd你好吗,哈哈,ANMOL";  
 int i = 0;  
 int j = strlen(t);
 char *enc = base64_encode(t, j);
 int len = strlen(enc);    
 char *dec = base64_decode(enc, len);    
 printf("\noriginal: %s\n", t);    
 printf("\nencoded : %s\n", enc);  
 printf("\ndecoded : %s\n", dec);   
 free(enc); 
 free(dec); 
 return 0;
}

char *base64_encode(const char* data, int data_len) {    
 //int data_len = strlen(data);    
 int prepare = 0;    
 int ret_len;   
 int temp = 0;  
 char *ret = NULL;   
 char *f = NULL;  
 int tmp = 0;    
 char changed[4];   
 int i = 0;
 ret_len = data_len / 3;
 temp = data_len % 3;  
 if (temp > 0)   
 {      
  ret_len += 1;
 }   
 ret_len = ret_len*4 + 1;  
 ret = (char *)malloc(ret_len);   
 if ( ret == NULL)    
 {       
  printf("No enough memory.\n");
  exit(0);  
 }    
 memset(ret, 0, ret_len); 
 f = ret;    
 while (tmp < data_len)    
 {      
  temp = 0; 
  prepare = 0;   
  memset(changed, '\0', 4);
  while (temp < 3) 
  {     
   //printf("tmp = %d\n", tmp);
   if (tmp >= data_len)  
   {           
    break; 
   }          

   prepare = ((prepare << 8) | (data[tmp] & 0xFF));   
   tmp++;       
   temp++;   
  }      
  prepare = (prepare<<((3-temp)*8));   
  //printf("before for : temp = %d, prepare = %d\n", temp, prepare);   
  for (i = 0; i < 4 ;i++ )  
  {          
   if (temp < i)
   {             
    changed[i] = 0x40;     
   }            
   else        
   {           
    changed[i] = (prepare>>((3-i)*6)) & 0x3F;  
   }          
   *f = base[changed[i]];   
   //printf("%.2X", changed[i]);     
   f++;      
  }    
 }   
 *f = '\0';
 return ret;
}

static char find_pos(char ch)
{   
 char *ptr = (char*)strrchr(base, ch);
 //the last position (the only) in base[]  
 return (ptr - base);
}

char *base64_decode(const char *data, int data_len)
{   
 int ret_len = (data_len / 4) * 3;  
 int equal_count = 0;  
 char *ret = NULL;  
 char *f = NULL;  
 int tmp = 0;  
 int temp = 0;   
 char need[3];   
 int prepare = 0; 
 int i = 0;  
 if (*(data + data_len - 1) == '=')  
 {       
  equal_count += 1; 
 }    
 if (*(data + data_len - 2) == '=')  
 {       
  equal_count += 1;
 }   
 if (*(data + data_len - 3) == '=')  
 {
  //seems impossible     
  equal_count += 1; 
 }   
 switch (equal_count)    
 {  
 case 0:   
  ret_len += 4;//3 + 1 [1 for NULL]      
  break;    
 case 1:      
  ret_len += 4;//Ceil((6*3)/8)+1      
  break;   
 case 2:      
  ret_len += 3;//Ceil((6*2)/8)+1      
  break;  
 case 3:        
  ret_len += 2;//Ceil((6*1)/8)+1       
  break;   
 }  
 ret = (char *)malloc(ret_len);  
 if (ret == NULL)  
 {      
  printf("No enough memory.\n");     
  exit(0); 
 }   
 memset(ret, 0, ret_len);    
 f = ret; 
 while (tmp < (data_len - equal_count))   
 {       
  temp = 0;  
  prepare = 0;   
  memset(need, 0, 4);   
  while (temp < 4)       
  {       
   if (tmp >= (data_len - equal_count))  
   {            
    break;      
   }           
   prepare = (prepare << 6) | (find_pos(data[tmp])); 
   temp++;        
   tmp++;       
  }      
  prepare = prepare << ((4-temp) * 6); 
  for (i=0; i<3 ;i++ )    
  {            
   if (i == temp)     
   {             
    break;       
   }            
   *f = (char)((prepare>>((2-i)*8)) & 0xFF);  
   f++;       
  }   
 }   
 *f = '\0'; 
 return ret;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值