【算法学习】base64 加密解密

base 加密解密

需要了解 base 加密解密,首先要了解字符编码。能够知道的是,在计算机的世界里,0和1就是全部,而目前计算机中显示的字母、数字、符号和中文等一系列其实都是通过0和1的组合,规定某个组合显示特定的字符。

通过将0和1的组合显示出字符的过程就是编码,不同的0和1的组合对应不同的字符,而这个对应关系就是该编码的索引表。而目前西文的编码就是 ASCII 编码。

所以当我们用主流的 ASCII 编码显示一段字符串的时候,如果想把它加密,那么我们应该看到的是这段字符串的二进制表现。

可以通过某种手法将这个二进制数组加工制造,那么就可以说是对这个字符串进行了加密。但是考虑到加密之后的解密,所以在加工制造的过程中,也要考虑到该加工制造需要一个可逆的过程进行解密。

base 加密解密其实可以想象成就是对一个二进制数组另一个编码的流程。

base16,base32和base64

base64 是用64(2的6次方)个特定 ASCII 字符表示256(2的8次方)个 ASCII 字符,3个 ASCII 字符经过 base64 编码后会变为4个字符,长度比原来增加1/3。密文不足4n用”=”补足。其索引表包含大写字母(A-Z),小写字母(a-z),数字(0-9)以及+/;

base32 是用32(2的5次方)个特定 ASCII 字符表示256个 ASCII 字符。5个 ASCII 字符经过 base32 编码后会变为8个字符(公约数为40),长度增加3/5。密文不足8n用“=”补足。其索引表包含大写字母(A-Z)和数字234567;

base16 是用16(2的4次方)个特定 ASCII 字符表示256个 ASCII 字符。1个 ASCII 字符经过 base16 编码后会变为2个字符,长度增加一倍。其索引表包含数字(0-9),字母(ABCDEF);

base64 详解

base64 加密其实就是将通过 ASCII 编码的字符转换成通过 base64 编码的字符的过程。解密则是反过来。

索引表

二进制 字符 二进制 字符 二进制 字符 二进制 字符 二进制 字符 二进制 字符 二进制 字符 二进制 字符
000000 A 001000 I 010000 Q 011000 Y 100000 g 101000 o 110000 w 111000 4
000001 B 001001 J 010001 R 011001 Z 100001 h 101001 p 110001 x 111001 5
000010 C 001010 K 010010 S 011010 a 100010 i 101010 q 110010 y 111010 6
000011 D 001011 L 010011 T 011011 b 100011 j 101011 r 110011 z 111011 7
000100 E 001100 M 010100 U 011100 c 100100 k 101100 s 110100 0 111100 8
000101 F 001101 N 010101 V 011101 d 100101 l 101101 t 110101 1 111101 9
000110 G 001110 O 010110 W 011110 e 100110 m 101110 u 110110 2 111110 +
000111 H 001111 P 010111 X 011111 f 100111 n 101111 v 110111 3 111111 /

加密过程详解

case 1

需要加密的字符串数组恰好是3的倍数

通过 ASCII 编码得到的字符以及其二进制表示

z l !
01111010 01101100 00100001

通过 base64 重新对二进制编码后的字符

011110 100110 110000 100001
e m w h

case 2

需要加密的字符串数组最后还剩2个, 密文后面补上1个‘=’。

通过 ASCII 编码得到的字符以及其二进制表示

z l  
01111010 01101100 00000000

通过 base64 重新对二进制编码后的字符

011110 100110 110000 000000
e m w =

case 3

需要加密的字符串数组最后还剩1个,密文后面补上2个‘=’。

通过 ASCII 编码得到的字符以及其二进制表示

z    
01111010 00000000 00000000

通过 base64 重新对二进制编码后的字符

011110 100000 000000 000000
e g = =

其实解密就是加密的逆过程,所以就不再复述。

C++代码

#include <iostream>
#include <string>
#include <bitset>

enum FUNCTION {BTS = 1, STB};
static const std::string BASE64 ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

//get int from BASE64
int charToInt(char c) {
    int res = -1;
    if(c == '/') {
        res = 63;
    }else if(c == '+') {
        res = 62;
    }else if(c >= 'A' && c <= 'Z') {
        res = 0 + c - 'A';
    }else if(c >= 'a' && c <= 'z') {
        res = 26 + c - 'a';
    }else if(c >= '0' && c <= '9') {
        res = 52 + c - '0';
    }else if (c == '=') {
        // Anyway, it will be delete at last.
        res = 0;
    }
    return res;
}

std::string base64_decode(std::string temp) {
    std::string decStr;
    std::bitset<24> bitStr;
    int equalSize = 0;
    //change base64 char to bitset
    for(int i = 0; i < 4; ++i) {
        if(temp[i] == '=') equalSize++;
        std::bitset<6> bit = charToInt(temp[i]);
        for(int j = 0; j < 6; ++j) {
            bitStr[6*(3-i) + j] = bit[j];
        }
    }
    // std::cout << bitStr << std::endl;
    //translate bit to int, then to char
    for(int i = 0; i < 3; ++i) {
        int binna = 0;
        int B = 1;
        for(int j = 0; j < 8; ++j) {
            binna += B * bitStr[8*(2-i) + j];
            B = B * 2;
        }
        decStr += binna;
    }
    return decStr.substr(0, 3 - equalSize);
}

void base64Tostring() {
    std::string temp;
    std::cout << "Please input the string for base64 decode.\n";
    std::getline (std::cin, temp);
    std::string resStr;
    //translate 4 base64 char to 3 normal char every time.
    while(temp.size() > 3) {
        resStr += base64_decode(temp.substr(0,4));
        temp = temp.substr(4, temp.size()-4);
    }
    std::cout << "base64 decode string is: " << resStr << std::endl;
}

std::string base64_encode(std::string temp, int length) {
    std::string base64;
    std::bitset<24> bitStr;
    //change normal char to bitset
    for(int i = 0; i < length; ++i) {
        std::bitset<8> bit = std::bitset<8>(temp[i]);
        for(int j = 0; j < 8; ++j) {
            bitStr[8*(2 - i) + j] = bit[j];
        }
    }
    // std::cout << bitStr << std::endl;
    //translate bitset to int every 6 bit, and get base64 char from BASE64.
    for(int i = 0; i < length + 1; ++i) {
        int binna = 0;
        int B = 32;
        for(int j = 1; j <= 6; ++j) {
            binna += B * bitStr[6*(4 -i) - j];
            B = B / 2;
        }
        base64 += BASE64[binna];
    }
    return base64;
}

void stringTobase64() {
    std::string temp;
    std::cout << "Please input the string for base64 encode.\n";
    std::getline (std::cin, temp);
    std::string resStr;
    //translate 3 normal char to 4 base64 char every time.
    while(temp.size() > 2) {
        resStr += base64_encode(temp.substr(0,3), 3);
        temp = temp.substr(3, temp.size()-3);
    }
    //when normal string smaller than 3, add '=' at last.
    if(temp.size() != 0) {
        resStr += base64_encode(temp.substr(0,3), temp.size());
        resStr += std::string(3-temp.size(), '=');
    }
    std::cout << "base64 encode string is: " << resStr << std::endl;

}

int main() {
    do{
        std::cout << "Please choose the function:(Input 0 means quit)"
        << "\n\t 1: base64Tostring"
        << "\n\t 2: stringTobase64"
        << "\n";
        int func;
        std::cin >> func;
		std::cin.ignore();
        if(func == 0) break;
        switch (func) {
        case BTS:
            base64Tostring();
            break;
        case STB:
            stringTobase64();
            break;
        default:
            std::cout << "Wrong number.\n";
            break;
        }
    }while (true);
    return 0;
}

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦