嗨我制作了一个基本的64编码器,其中一些工作但不是100%而且它让我疯狂为什么它不起作用。
int b64_encode(FILE *in, FILE *out)
{
do
{
char outbuf [76+3];// room for null \n \r
char inbuf [57];//ratio 4ascii/3chars
for(int i=0; i < sizeof(inbuf);i++)
inbuf[i]=0;
int i1;
int i2;
int i3;
int o1;
int o2;
int o3;
int o4;
int combine;
size_t read_cnt;
read_cnt = fread(inbuf,1,sizeof(inbuf),in);
for (int i = 0; i < read_cnt; i=i+3)
{
i3 = inbuf[i+2];
i2 =inbuf[i+1] << 8;
i1 = inbuf[i] << 16;
combine = i1+i2+i3;
o4 = (combine & 0x3f);
combine = combine >> 6;
o3 = (combine & 0x3f);
combine = combine >> 6;
o2 = (combine & 0x3f);
combine = combine >> 6;
o1 = (combine & 0x3f);
combine = combine >> 6;
outbuf[i*4/3]=ENCODE[o1];
outbuf[i*4/3+1]=ENCODE[o2];
outbuf[i*4/3+2]=ENCODE[o3];
outbuf[i*4/3+3]=ENCODE[o4];
}
for(int i=0; i < sizeof(outbuf);i++)
{
if(outbuf[i]==0)
{
outbuf[i+2]='\0';
outbuf[i]='\r';
outbuf[i+1]='\n';
i=sizeof(outbuf);
}
}
//padding
if((read_cnt%3)==2)
{
int t= (int)read_cnt;
int temp= ((t/3)+1)*4;
outbuf[temp-1] = '=';
}
if((read_cnt%3)==1)
{
int t= (int)read_cnt;
int temp= ((t/3)+1)*4;
outbuf[temp-1] = '=';
outbuf[temp-2] = '=';
}
//for(int i=0; i < sizeof((read_cnt)*4/3);i++)
printf("%s",outbuf);
}
while(feof(in)==0);
return 0;
}
当我输入这个例子时,我会在维基百科上看到'人是杰出的,不仅仅是因为他的理性,而是来自这个奇异的激情来自 其他动物,这是一种心灵的欲望,通过坚持不懈的喜悦 在持续和不知疲倦的一代知识中,超越了空缺 任何肉体的快感都会激烈。',它应该是'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4 ='
但我得到
“TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz IHNpbmd1bGFyIHBhc3Npb24gZnJvbQpvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodAppbiB0aGUgY29udGlu dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo ZSBzaG9ydAp2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4KZGdlLCBleGNlZWRzIHRo'
这是同样的事情,但最后有一点额外的'KZGdlLCBleGNlZWRzIHRo'。有人可以帮我理解这些额外代码的来源吗?非常感谢
答案 0 :(得分:0)
随意投票,但我想随意猜测:尝试......
for (int i = 0; i < read_cnt - 2; i=i+3)
......而不是......
for (int i = 0; i < read_cnt; i=i+3)
我试图通过查看Wikipedia article来了解您到底想要做什么,但我不能说我已经正确理解了整个事情。
答案 1 :(得分:0)
您的代码中存在几个问题。
您正在阅读数据缓冲区。
i3 = inbuf[i+2];
i2 = inbuf[i+1] << 8;
你真的应该添加支票,因为没有获得[0..read_cnt-1]以外的值
您正在对有符号整数使用shift。在处理非ASCII文本或二进制数据时,这会给你带来有趣的结果
i3 = (unsigned char*)inbuf[i+2];
i2 = (unsigned char*)inbuf[i+1] << 8;
i1 = (unsigned char*)inbuf[i] << 16;
原因是char
是一个有符号的类型,当char设置了第7位(超过int
时)时,它会扩展为0x7f
并设置所有高位。
另外combine
应 unsigned
。
编码循环后,您没有终止outbuf
。
您正试图找到0
,但它不存在......
您可以尝试以下方法,而不是多个填充:
int pos = read_cnt * 4;
switch (read_cnt % 3)
{
case 1: outbuf[pos++] = '=';
case 2: outbuf[pos++] = '=';
case 0: outbuf[pos++] = '\r';
outbuf[pos++] = '\n';
outbuf[pos] = 0;
}
read_cnt
应为 ssize_t