跳转至

CSP-J 2021 初赛 阅读程序 第2题

前置技能:Base64编码原理

base64加密原理详解_小白-CSDN博客_base64加密

img

img

正文:

#include <iostream> 
#include <string>

using namespace std;

char base[64];
char table[256];

void init()
{   
    // A~Z的下标是0~25
    for (int i = 0; i < 26; i++) base[i] = 'A' + i;
    // a~z的下标是26~51
    for (int i = 0; i < 26; i++) base[26 + i] = 'a' + i;
    // 0~9的下标是52~61
    for (int i = 0; i < 10; i++) base[52 + i] = '0' + i;
    // 62存+号,63存/号
    base[62] = '+', base[63] = '/';

    // table是base的逆,
    // table[base[i]] = i, table[字符] = 这个字符在base里的下标
    // 0xff,table[i]是char类型的
    // 这里(int)(table[0]),输出的是-1
    // 如果int x = 0xff, 输出的是255
    for (int i = 0; i < 256; i++) table[i] = 0xff;
    for (int i = 0; i < 64; i++) table[base[i]] = i;

    // =号
    table['='] = 0;
}

string decode(string str)
{
    string ret;

    int i;
    for (i = 0; i < str.size(); i += 4) {   // 步长是4
        // 000000 000000 000000 000000
        // 000000 00|0000 0000|00 000000
        // 这样4个6位,    4*6=24位
        // 变换成了3个8位,3*8=24位
        ret += table[str[i]] << 2 | table[str[i + 1]] >> 4;

        if (str[i + 2] != '=')  // & 0x0f 取后4位
            ret += (table[str[i + 1]] & 0x0f) << 4 | table[str[i + 2]] >> 2;
        if (str[i + 3] != '=')  // << 6 左移6位,最后两位顶到了最左边,然后异或上6位,就是加上后面的6位
            ret += table[str[i + 2]] << 6 | table[str[i + 3]];
    }
    return ret;
}


int main()
{
    init();

    // 这个地方如果是 unsigned char,输出是255
    // 但 应该是char,输出-1
    cout << int(table[0]) << endl;

    string str;
    cin >> str;

    // 解码过程
    cout << decode(str) << endl;

    return 0;
}

img

错。解密过程中,可以解密成其他字符,因为解密出来的字符串是用ASCII码拼的
在base和table只是做了这些现有的字符的加解密关系

img


img

对。上面已有解释,0x表示16进制数

img

B。decode里面只有一个for循环,O(n)

img

img

img

img