课后自主练习(字符串)1048. Base64编码 easy《编程思维与实践》个人学习笔记

题目

Base64 编码是一种编码方式,通常用于把二进制数据编码为 64 个可打印字符数据。

Base64 编码采用的 64 个可打印字符为:A-Z、a-z、0-9、+、/

64 个字符只需要用 6 位二进制来表示,对应的十进制数值为 0~63。
在这里插入图片描述
长度为 3 个字节(24 位)的数据经过 Base64 编码后就变为 4 个字符。

例如,字符串 “Man” 经过 Base64 编码后为:”TWFu”。其编码过程如下:

第一步,’M’、’a’、’n’ 三个字符的 ASCII 码分别是 77、97、110,对应的二进制值是 01001101、01100001、01101110,将它们连成一个 24 位的二进制串 010011010110000101101110。

第二步,将这个 24 位的二进制串分成 4 组,每组 6 个二进制位:010011、010110、000101、101110。

第三步,在每组前面加两个 00,扩展成 32 个二进制位,即四个字节:00010011、00010110、00000101、00101110。它们的十进制值分别是 19、22、5、46。

第四步,根据上面对照表,得到每个值对应 Base64 编码,即 T、W、F、u。
在这里插入图片描述
如果待编码数据的字节数不是 3 的倍数,则其位数不是 6 的倍数,则需在原数据后面添加若干个 0,使其位数是 6 的倍数。

如果转换后不满 4 个字符,后面用等号 (=) 填充。

例如,字符串 “A” 经过 Base64 编码后为:”QQ==”。其编码过程如下:

在这里插入图片描述

例如,字符串 “+p” 经过 Base64 编码后为:”K3A=”。其编码过程如下:
在这里插入图片描述
在这里插入图片描述
数据
10
?
sdfder=-040304?;><erererererfdfdkferqwertyuiopasdfghjklzxcvbnm1232434938980930302edjf;±*,.gfort451
ABCDEFGDHJIMOP
0-1
p+
Iamateacher
pq=ty
dsf3294
2389892132093029erue28302
+435dfkjg2

答案
case #0:
Pw==
case #1:
c2RmZGVyPS0wNDAzMDQ/Oz48ZXJlcmVyZXJlcmZkZmRrZmVycXdlcnR5dWlvcGFzZGZnaGprbHp4Y3Zibm0xMjMyNDM0OTM4OTgwOTMwMzAyZWRqZjsrLVwqLC5nZm9ydDQ1MQ==
case #2:
QUJDREVGR0RISklNT1A=
case #3:
MC0x
case #4:
cCs=
case #5:
SWFtYXRlYWNoZXI=
case #6:
cHE9dHk=
case #7:
ZHNmMzI5NA==
case #8:
MjM4OTg5MjEzMjA5MzAyOWVydWUyODMwMg==
case #9:
KzQzNWRma2pnMg==

思路

① 先开一个字符串来储存BASE64的编码
②将输入的字符串分两个部分
一个是可以被3整除的部分,一个是剩余的1或2个字符
③转换成二进制的字符串后再转换成对应6个字节的十进制
//注意转换二进制得在8*n的位置上插入
在这里插入图片描述

代码

#include<iostream>
#include<cstring>
using namespace std;


string Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

void trans(string s, int len)
{
    string bin;
    for(int i = 0; i < len; i++)
    {
        for(int j = 0; j < 8; j++)
        {   
            //cout << "bin " << bin << " s[i] " << (int)s[i] <<" ?? " << s[i] <<" i " << i << endl;
            if(!s[i])
            {
                bin.insert(i * 8,1,'0');
            }
            else
            {
                int temp = s[i] % 2;
                bin.insert(i * 8, 1, '0' + temp);
                s[i] /= 2;
            }
            //cout << "bin " << bin << " s[i] " << (int)s[i] << endl;
        }
    }

    int * c = new int[10000];
    memset(c,0,40000);
    int loc = 0;
    int times = 0;
    int blen = bin.length();

    int flag = 0;
    if(blen % 6)
    {
        flag = 1;
        while(blen < 6 * (len + 1))
        {
            bin += '0';
            blen++;
        }
    }
    
    for(int i = 0; i < blen; i++)
    {
        c[loc] *= 2;
        c[loc] += (bin[i] - '0');
        times++;
        if(times == 6)
        {
            times = 0;
            loc++;
        }
    }
    
    for(int i = 0; i < loc; i++)
        {cout << Base64[c[i]];}
    if(flag)
    {
        for(int i = 0; i < 3 - len ;i++)
        {
            cout << "=";
        }
    }
}

int main()
{
    int t;
    cin >> t;
    for(int i = 0; i < t; i++)
    {
        string str;
        cin >> str;
        int len = str.length();
        int group = len / 3;//看有多少组

        int flag = 0;
        if(len % 3)
            flag = len % 3;

        
        cout << "case #" << i << ":"<<endl;

        //put(group * 3,0,str);先把前面的内容搞定好
        trans(str,group * 3);

        if(flag)
        {   
            string s1;
            for(int j = flag; j > 0; j--)
            {
                s1 += str[len - j];//
            }
            trans(s1,s1.length());
            //put(len, out * 3, str, 1);
        }


        
        cout << endl;
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值