c语言Base64算法的实现

博客介绍了Base64作为常见的8Bit字节编码方式,常用于HTTP环境下的标识信息传输,如Hibernate中的UUID编码。内容探讨了在需要将二进制数据编码为适合URL的形式时,Base64编码的优势——简洁且不可读。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

百科对base64的简述:

Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

const char _Base[]={"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="};

static union
{
	struct  
	{
		unsigned long a:6;
		unsigned long b:6;
		unsigned long c:6;
		unsigned long d:6;
	}Sdata;
	unsigned char c[3];
}Udata;

char * Encbase64(char * orgdata,unsigned long orglen,unsigned long *newlen);

char * Decbase64(char * orgdata,unsigned long orglen);

int main(int argc,char *agv[])
{
	unsigned long nlen;
	
	printf("%s\n",Encbase64("i love travel",strlen("i love travel"),&nlen));
	
	printf("%s\n",Decbase64("aSBsb3ZlIHRyYXZlbA==",strlen("aSBsb3ZlIHRyYXZlbA==")));
	return 0;
}

char * Encbase64(char * orgdata,unsigned long orglen,unsigned long *newlen)
{
	char *p=NULL,*ret=NULL;
	int tlen=0;
	if (orgdata==NULL|| orglen==0)
		return NULL ;
	tlen=orglen/3;
	if(tlen%3!=0) tlen++;
	tlen=tlen*4;
	*newlen=tlen;
	if ((ret=(char *)malloc(tlen+1))==NULL)
		return NULL;
	memset(ret,0,tlen+1);
	p=orgdata;tlen=orglen;

	int i=0,j=0;
	while(tlen>0)
	{
		Udata.c[0]=Udata.c[1]=Udata.c[2]=0;
		for (i=0;i<3;i++)
		{
			if (tlen<1) break;
			Udata.c[i]=(char)*p;
			tlen--;
			p++;
		}
		if (i==0) break;
		switch (i)
		{
			case 1:
				/*ret[j++]=_Base[Udata.Sdata.d];
				ret[j++]=_Base[Udata.Sdata.c];
				ret[j++]=_Base[64];
				ret[j++]=_Base[64];*/
				ret[j++]=_Base[Udata.c[0]>>2];
				ret[j++]=_Base[((Udata.c[0]&0x03)<<4)|((Udata.c[1]&0xf0)>>4)];
				ret[j++]=_Base[64];
				ret[j++]=_Base[64];
				break;
			case 2:
				/*ret[j++]=_Base[Udata.Sdata.d];
				ret[j++]=_Base[Udata.Sdata.c];
				ret[j++]=_Base[Udata.Sdata.b];
				ret[j++]=_Base[64];*/
				ret[j++]=_Base[Udata.c[0]>>2];
				ret[j++]=_Base[((Udata.c[0]&0x03)<<4)|((Udata.c[1]&0xf0)>>4)];
				ret[j++]=_Base[((Udata.c[1]&0x0f)<<2)|((Udata.c[2]&0xc0)>>6)];
				ret[j++]=_Base[64];
				break;
			case 3:
				/*ret[j++]=_Base[Udata.Sdata.d];
				ret[j++]=_Base[Udata.Sdata.c];
				ret[j++]=_Base[Udata.Sdata.b];
				ret[j++]=_Base[Udata.Sdata.a];*/
				ret[j++]=_Base[Udata.c[0]>>2];
				ret[j++]=_Base[((Udata.c[0]&0x03)<<4)|((Udata.c[1]&0xf0)>>4)];
				ret[j++]=_Base[((Udata.c[1]&0x0f)<<2)|((Udata.c[2]&0xc0)>>6)];
				ret[j++]=_Base[Udata.c[2]&0x3f];
				break;
			default:
				break;
		}
	}
	ret[j]='\0';
	return ret;
}

char * Decbase64(char * orgdata,unsigned long orglen)
{
	char *p,*ret;
	int len;
	char ch[4]={0};
	char *pos[4];
	int  offset[4];
	if (orgdata==NULL || orglen==0)
	{
		return NULL;
	}
	len=orglen*3/4;
	if ((ret=(char *)malloc(len+1))==NULL)
	{
		return NULL;
	}
	p=orgdata;
	len=orglen;
	int j=0;
	
	while(len>0)
	{
		int i=0;
		while(i<4)
		{
			if (len>0)
			{
				ch[i]=*p;
				p++;
				len--;
				if ((pos[i]=(char *)strchr(_Base,ch[i]))==NULL)
				{
					return NULL;
				}
				offset[i]=pos[i]-_Base;
				
			}
			i++;
		}
		if (ch[0]=='='||ch[1]=='='||(ch[2]=='='&&ch[3]!='='))
		{
			return NULL;
		}
		ret[j++]=(unsigned char)(offset[0]<<2|offset[1]>>4);
		ret[j++]=offset[2]==64?'\0':(unsigned char)(offset[1]<<4|offset[2]>>2);
		ret[j++]=offset[3]==64?'\0':(unsigned char)((offset[2]<<6&0xc0)|offset[3]);
	}
	ret[j]='\0';
	return ret;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值