base64的加密与解密

前言

经过多方面查找后,以及好几天的努力,才完成了base64的编码与解码工作。水平有限,代码有些繁琐,希望大家批评指正。

原理

base64的索引表
base64索引表
-base64的编码都是按字符串长度,以每3个8bit的字符为一组,
-然后针对每组,首先获取每个字符的ASCII编码,
-然后将ASCII编码转换成8bit的二进制,得到一组3*8=24bit的字节
-然后再将这24bit划分为4个6bit的字节,并在每个6bit的字节前面都填两个高位0,得到4个8bit的字节
-然后将这4个8bit的字节转换成10进制,对照Base64索引表,得到对应编码后的字符。
-base64编码是,3个字符变为4个字符。若编码字符不足3个(二进制不是6的倍数),则在后面补0,使之可以形成一个新字符;若最后几个字符不能转化出4个字符,则在后面直接补‘=’。详见下表
在这里插入图片描述

代码实现

编码

#include<stdio.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
char boss[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
int sumb(int a)
{
    int i,j,m,n;
    int sum=1;
    for(i=0;i<a;i++)
    {
        sum*=2;
    }
    return sum;
}
int b_to_o(char str[])
{
    int m,n,i,j;
    int num=0;
    m=strlen(str);
    for(i=0;i<m;i++)
    {
        j=str[i]-'0';
        num+=j*sumb(m-i-1);
    }
    return num;
}
int main()
{
    int m,n,i,j,k,l,c,len;
    char str[10000]={0};    //用来储存出初始字符串
    char temp[1000]={0};    //每六个一组取出后,形成新的字符串,储存于其中
    char num[20000]={0};     //字符串转化成二进制之后,形成一个字符串,储存
    char tp[1000]={0};   //2进制字符串
    char link[1000]={0};   //中转
    int mud[1000];
    char r,s,t;
    printf("请输入待加密的字符串:");
    gets(str);
    len=strlen(str);
    if(len%3==0)
    {
        for(i=0;i<len;i++)
        {
            m=str[i];
           // printf("%d\n",m);
            itoa(m,tp,2);
            sprintf(link,"%08s",tp);
            strcat(num,link);
            //printf("***\n");



        }
        //printf("%s\n",num);
        l=(len*8)/6;
        //printf("%d\n",l);
        for(i=0;i<l;i++)
        {
            c=0;
            for(j=0+6*i;j<6*(i+1);j++)
            {
                temp[c]=num[j];
                c++;


            }
            //puts(temp);
            mud[i]=b_to_o(temp);
           // printf("%d\n",mud[i]);
        }
        //puts(mud);
        for(i=0;i<l;i++)
        {
            printf("%c",boss[mud[i]]);//printf("***\n");
        }
    }
    else
    {
        int mm,mf;
        mm=len%3;
        len=len-mm;
        char ww[1000]={0};
        for(i=0;i<len;i++)
        {
            ww[c]=str[i];
            c++;
        }
        for(i=0;i<len;i++)
        {
            m=str[i];
           // printf("%d\n",m);
            itoa(m,tp,2);
            sprintf(link,"%08s",tp);
            strcat(num,link);
            //printf("***\n");



        }
        //printf("%s\n",num);
        l=(len*8)/6;
        //printf("%d\n",l);
        for(i=0;i<l;i++)
        {
            c=0;
            for(j=0+6*i;j<6*(i+1);j++)
            {
                temp[c]=num[j];
                c++;


            }
            //puts(temp);
            mud[i]=b_to_o(temp);
        }
       // printf("%d\n",mud[i-1]);
        mf=i;
       // printf("**\n");
        memset(temp,0,sizeof(temp));
        memset(num,0,sizeof(num));
        //printf("**\n");
        if(mm==1)
        {
            m=str[len];
            itoa(m,tp,2);
            sprintf(link,"%08s",tp);
           // printf("**\n");
            strcat(num,link);
            char pp[]="0000";
            strcat(num,pp);
            //puts(num);
           // printf("strlen is %d\n",strlen(num));
           // puts(num);
            for(i=0;i<2;i++)
            {
                c=0;
                for(j=0+6*i;j<6*(i+1);j++)
                {
                    temp[c]=num[j];
                    c++;


                }
            //puts(temp);
                    mud[mf++]=b_to_o(temp);

                 //   printf("%d\n",mud[mf]);
            }
            mud[mf]=64;
            mud[mf+1]=64;

        }
        else if(mm==2)
        {
            for(i=1; i<=mm; i++)
            {
                m=str[len-i];
                itoa(m,tp,2);
                sprintf(link,"%08s",tp);
               // printf("**\n");
                strcat(num,link);
            }

            char pp[]="00";
            strcat(num,pp);
            //puts(num);
           // printf("strlen is %d\n",strlen(num));
            //puts(num);
            for(i=0;i<3;i++)
            {
                c=0;
                for(j=0+6*i;j<6*(i+1);j++)
                {
                    temp[c]=num[j];
                    c++;


                }
            //puts(temp);
                    mud[mf++]=b_to_o(temp);

                    //printf("%d\n",mud[mf]);
            }
            mud[mf]=64;
        }
        for(i=0;i<l+4;i++)
        {
            //printf("%d\n",mud[i]);
            printf("%c",boss[mud[i]]);//printf("***\n");
        }


    }

}

解密

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
char boss[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

int c_to_n(char s)
{
    int i,j,k,len;
    len=strlen(boss);

    for(i=0;i<len;i++)
    {
        if(boss[i]==s)
            break;
    }
    return i;
}
int sumb(int a)
{
    int i,j,m,n;
    int sum=1;
    for(i=0;i<a;i++)
    {
        sum*=2;
    }
    return sum;
}
int b_to_o(char str[])
{
    int m,n,i,j;
    int num=0;
    m=strlen(str);
    for(i=0;i<m;i++)
    {
        j=str[i]-'0';
        num+=j*sumb(m-i-1);
    }
    return num;
}
int main()
{
    int i,j,m,n,k,len,c,len1,len2,len3,flag=0,mf,p;
    int main[1000]={0};     //储存最后结果
    char str[10000]={0};
    char s1[10000]={0};    //前面能被3整除的字符串
    char s2[100]={0};    //the str behind a,
    char bin[100]={0};  //十进制化为二进制
    char link[100]={0};   //中转
    char num[10000]={0};   //conact the strs
    char temp[1000]={0};    //取出字符串
    printf("请输入待解密的字符串:");
    gets(str);
    len=strlen(str);
    if(str[len-1]=='=')
    {
        for(i=0; i<len-4; i++)
        {
            s1[i]=str[i];

        }
        c=0;
        if(str[len-2]=='=')
        {
            flag=2;
            for(j=len-4;j<len-2;j++)
            {
                s2[c]=str[j];
                c++;
            }
        }
        else
        {
            flag=1;
            for(j=len-4;j<len-1;j++)
            {
                s2[c]=str[j];
                c++;
            }
        }
        len1=strlen(s1);
        len2=strlen(s2);
        for(i=0;i<len1;i++)
        {
            m=c_to_n(s1[i]);
            itoa(m,bin,2);
            sprintf(temp,"%06s",bin);
            strcat(num,temp);

        }
       // printf("%d\n",strlen(num));
        memset(bin,0,sizeof(bin));
        memset(temp,0,sizeof(temp));
        for(i=0;i<len2;i++)
        {
            m=c_to_n(s2[i]);
            //printf("%d\n",m);
            itoa(m,bin,2);
            //puts(bin);
            sprintf(temp,"%06s",bin);
           // puts(temp);
            strcat(num,temp);

        }
        len3=strlen(num);
        //printf("*%d\n",len2);
        if(flag==1)
        {
            num[len3-2]='\0';
        }
        else if(flag==2)
        {
            num[len3-4]='\0';
        }
        len3=strlen(num);
        k=len3/8;
        for(i=0;i<k;i++)
        {
            c=0;
            for(j=0+8*i;j<8*(i+1);j++)
            {
                temp[c]=num[j];
                c++;
            }
            main[i]=b_to_o(temp);

        }
        mf=i;
        for(i=0;i<mf;i++)
        {
           // printf("%d",main[i]);
            printf("%c",main[i]);
        }
    }
    else
    {
        for(i=0;i<len;i++)
        {
            m=c_to_n(str[i]);
            itoa(m,bin,2);
            sprintf(link,"%06s",bin);
            strcat(num,link);

        }
      //  puts(num);
        len1=strlen(num);
        p=len1/8;
        for(i=0;i<p;i++)
        {
            c=0;
            for(j=0+8*i;j<8*(i+1);j++)
            {
                temp[c]=num[j];
                c++;

            }
            //printf("it is temp :%s\n",temp);
            main[i]=b_to_o(temp);
           // printf("%d\n",main[i]);

        }
        mf=i;
        for(i=0;i<mf;i++)
        {
            printf("%c",main[i]);
        }

    }

}

参考

https://www.cnblogs.com/diligenceday/p/6002382.html
http://www.cnblogs.com/hongru/archive/2012/01/14/2321397.html
https://baike.baidu.com/item/base64/8545775?fr=aladdin

猜你喜欢

转载自blog.csdn.net/weixin_43360152/article/details/87895619