《编程思维与实践》1047.Base64编码

《编程思维与实践》1047.Base64编码

题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路

直接模拟:将每个Base64编码值都分为两部分:前半部分由上一个字符求得,后半部分由下一个字符求得.
特别地,如果字符为第一个或最后一个,则直接可以求得Base64编码.
如下图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
其中,% 2 n 2^n 2n表示取出后n位的二进制位,

这是因为 N   %   2 n = ( 2 k + 2 k − 1 + . . . + 2 + 2 0 )   %   2 n = 2 n − 1 + . . . + 2 + 2 0 N\,\%\,2^n=(2^{k}+2^{k-1}+...+2+2^0)\,\%\,2^n=2^{n-1}+...+2+2^0 N%2n=(2k+2k1+...+2+20)%2n=2n1+...+2+20;
如果字符总数不为3的倍数,则需要添加’='对应的编码(不妨记为64),
之后只需要遍历字符串即可,每读三次更新一轮.

注意的点:

1.读取前半部分时指标不需要++,读取后半部分时才++,特别地,处于开头或者最后一个字符时,需要直接++;

2.需要补’=‘的情况只有非3的倍数的情况,由于读取编码前半部分时指标没有++,所以补’='时需要++;

代码

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

char chart[66]={"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="};  //'='编码记为64

int main()
{
	int T;
	scanf("%d",&T);
	for(int t=0;t<T;t++)
	{
		char s[101];
		scanf("%s",s);
        char ans[300];  //answer 存Base64编码
		printf("case #%d:\n",t);
        int j=0,cnt=0;  //j为ans指标   cnt记录读几个字符
		for(int i=0;i<strlen(s);i++) 
		{
            if(cnt==0) //处理每三个字符中的第一个
            {
                ans[j++]=s[i]>>2;      //第一个Base64 开头直接++
                ans[j]=(s[i]%4)<<4;    //第二个Base64的前半部分
            }
            else if(cnt==1) //处理第二个
            {
                ans[j++]+=s[i]>>4;   //第二个Base64的后半部分
                ans[j]=(s[i]%16)<<2;  //第三个Base64的前半部分  
            }
            else	//处理第三个
            {
                ans[j++]+=s[i]>>6;   //第三个Base64的后半部分 
                ans[j++]=s[i]%64;	//第四个Base64 最后一个也++ 
            }
            cnt=(++cnt)%3;    //注意这里要先自增再模3 每3次cnt更新重置为0
		}
        if(cnt==1)   //剩一个字符
        {
            j++;    //因为只读前半部分没有++ 所以需要人为++
            ans[j++]=64;   //补两个'='
            ans[j++]=64;
        }
        else if(cnt==2)  //剩两个字符
        {
            j++;  //因为只读前半部分没有++ 所以需要人为++
            ans[j++]=64;
        }
        for(int i=0;i<j;i++)
        {
            printf("%c",chart[ans[i]]);   //按编码输出对应的字符
        }
        printf("\n");
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值