我的B64编码器不起作用

时间:2014-02-16 01:13:00

标签: c encoding character-encoding base64 decode

嗨我制作了一个基本的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 dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmF​​uY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4 ='

但我得到

“TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz IHNpbmd1bGFyIHBhc3Npb24gZnJvbQpvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmF​​uY2Ugb2YgZGVsaWdodAppbiB0aGUgY29udGlu dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo ZSBzaG9ydAp2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4KZGdlLCBleGNlZWRzIHRo'

这是同样的事情,但最后有一点额外的'KZGdlLCBleGNlZWRzIHRo'。有人可以帮我理解这些额外代码的来源吗?非常感谢

2 个答案:

答案 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)

您的代码中存在几个问题。

  1. 您正在阅读数据缓冲区。

    i3 = inbuf[i+2];
    i2 = inbuf[i+1] << 8;
    

    你真的应该添加支票,因为没有获得[0..read_cnt-1]以外的值

  2. 您正在对有符号整数使用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

  3. 编码循环后,您没有终止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;
    }
    
  4. read_cnt 应为 ssize_t