C语言编程:编写一个函数base64加密

函数功能
利用Base64编码原理将字符串进行编码,编码原理为:每个字节8位,每次取出3个字节,也就是3 x 8 = 24 位。然后每次从此24位中取出6位,然后在前端补2位0,组成新的8位,也就是一个字节。这样就将3个字节转换成了4个字节。由于前面两位都是0,所以转换后的每个字节能表示的最大数字为63, 也就是说转换后的每个字节只可能是0-63中的一个数字。
然后根据规范给出的Base64索引表,将0-63 这64个数字转换成"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"中的一个。
当最后取出3个字节不够时,不够的位置补0,并且最后少一个字节时编码的最后加一个“=”,少两个字节时加两个"="。
详细原理请参见附录。
函数原型
int encode_string(char* str, unsigned int length, char* stat);
参数说明
str是传入的被操作字符串,字符串长度不超过100。
length 传入字符串的长度。
stat是被写入的地址,即将str数组进行编码后写到stat中。(注:不需要在函数中给stat动态分配内存,stat数组大小已经定义为150,因此编码结束后,需要手动写入结束字符)。
返回值及意义
0 操作成功;
1 str为空,字符串长度为0;
2 字符串长度超过限制,即字符串长度超过100。
备注
参考实现方法:基于Base64编解码原理,我们把每三个byte的数据放在24bit的缓冲区,可以定义一个unsigned int 类型的变量temp,这个变量会占4个字节的内存,我们只用其后面的3个字节来作为缓冲区。每次将数据赋值到缓冲区前,让这个变量等于0,然后依次将三个byte的数据填入缓冲区,最先填的byte数据需要左移16位,然后与temp进行或运算。仿此方法填入后面两个byte数据。

数据填充完成后,从高位开始,每次取6bit的数据,方法是:对temp进行位运算,右移6的倍数,然后与上0x3F。需要取4次,然后根据取到的数去索引表找对应的字符,填入stat中。这里有两个方法实现:
1. 创建一个char数组,把64个字符写入数组中,通过数组寻找字符。
2. 通过规律寻找字符,进行if else判断,取到的数在0-25间,’A’+取到的数。取到的数在26-51间,’a’+取到的数-26。取到的数在52-61间,’0’+取到的数-52。取到的数为62,’+’,取到的数为63,’/’。
特殊情况处理:字符串长度不是3的整数倍。可以强制使长度为3的整数倍,算法:重新定义长度length1,length1等于length除以3加上1再乘以3。这就保证length1比length大,且为3的整数倍。以length1分配新的一块内存给str1,在length长度内,填入str数据,超过部分填入0。
最后根据length与length1的差值来在stat的最后填入’=’。差值为0,不填。差值为1,填入1个’=’。差值为2,填入2个’=’。

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

const char *chlist = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

int encode_string(char* str, unsigned int length, char* stat) {
char s[103];
int i,j;
unsigned temp;
if(length <= 0) return 1;
if(length > 100) return 2;
str[length] = '\0';
strcpy(s,str);
while(strlen(s) % 3) strcat(s,"=");
for(i = 0,j = 0; s[i]; i += 3,j += 4) {
temp = s[i];
temp = (temp << 8) + s[i + 1];
temp = (temp << 8) + s[i + 2];
stat[j + 3] = chlist[temp & 0X3F];
temp >>= 6;
stat[j + 2] = chlist[temp & 0X3F];
temp >>= 6;
stat[j + 1] = chlist[temp & 0X3F];
temp >>= 6;
stat[j + 0] = chlist[temp & 0X3F];
}
stat[j] = '\0';
return 0;
}

int Index(char ch) {
int i;
for(i = 0; chlist[i]; ++i) {
if(chlist[i] == ch)
return i;
}
return -1;
}

void decode_string(char *s, char *t) {
unsigned temp;
int i,j,k,len = strlen(s);
if(len % 4) {
printf("无效数据。\n");
exit(2);
}
for(i = 0,j = 0; i <= len; i += 4,j += 3) {
temp = 0;
for(k = 0; k < 4; ++k)
temp = (temp << 6) + Index(s[i + k]);
for(k = 2; k >= 0; --k) {
t[j + k] = temp & 0XFF;
temp >>= 8;
}
}
t[j + k] = '\0';
}

int main() {
char s[100] = "1a2a3s4dff5fj6u7M8B9P0O1U2";
char t[150],u[100];
printf("s = %s\n",s);
encode_string(s,strlen(s),t);
printf("t = %s\n",t);
decode_string(t,u);
printf("u = %s\n",u);
return 0;
}

温馨提示:答案为网友推荐,仅供参考

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网