CTF学记之base64

2023.10.22 

Base64的简介

Base64就是包括小写字母a-z,大写字母A-Z,数字0-9,符号+/组成的64个字符的字符集,另外包括填充字符=。任何符号都可以转换成这个字符集中的字符,这个转化过程就叫做Base64编码。

Base64实现方式 

Base64编码要求把3个8位字节转化为4个6位的字节,之后在6位的前面补两个0,形成8位一个字节的形式。如果剩下的字符不足3个字节,则用0填充,输出字符使用=,因此编码后输出的文本末尾可能会出现1个或2个=

编码表

0A16Q32g48w
1B17R33h49x
2C18S34i50y
3D19T35j51z
4E20U36k520
5F21V37l531
6G22W38m542
7H23X39n553
8I24Y40o564
9J25Z41p575
10K26a42q586
11L27b43r597
12M28c44s608
13N29d45t619
14O30e46u62+
15P31f47v63/

编码过程

以 flag 为例

flag
ASCII二进制01100110011011000110000101100111
合并01100110011011000110000101100111
6bit为一组011001100110110001100001011001110000000000000000
高位补00001100100100110001100010010000100011001001100000000000000000000
对应编码表索引253849332548
对应编码表字符ZmxhZw==
转换结果ZmxhZw==

 python加解密脚本实现

# Base64编码
def base64_encode(plain_text):
    # Base64字符集
    b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    
    # 将文本转换为二进制字符串
    binary_text = ''.join(format(ord(c), '08b') for c in plain_text)
    
    # 补齐长度到6的整数倍
    binary_text += '0' * ((6 - len(binary_text) % 6) % 6)
    
    # 将6位二进制转换为Base64字符
    base64_text = ''.join(b64[int(binary_text[i:i+6], 2)] for i in range(0, len(binary_text), 6))
    
    # 在末尾补齐=
    base64_text += '=' * ((4 - len(binary_text) // 6) % 4)
    
    return base64_text

# Base64解码
def base64_decode(base64_text):
    # Base64字符集
    b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    
    # 去除末尾的=
    base64_text = base64_text.rstrip('=')
    
    # 将Base64字符转换为二进制字符串
    binary_text = ''.join(format(b64.index(c), '06b') for c in base64_text)
    
    # 将8位二进制转换为字符
    plain_text = ''.join(chr(int(binary_text[i:i+8], 2)) for i in range(0, len(binary_text), 8))
    
    return plain_text

# 主函数
def main():
    # 用户选择操作类型
    num = int(input("请选择你要输入的类型的序号:\n1、加密\n2、解密\n----------\n输入序号:"))
    
    if num == 1:
        # 加密
        plain_text = input("请输入:\n")
        print("加密完成:\n", base64_encode(plain_text))
    elif num == 2:
        # 解密
        cipher_text = input("请输入:\n")
        print("解密完成:\n", base64_decode(cipher_text))
    else:
        print("输入错误")

if __name__ == "__main__":
    main()

C++加解密脚本实现

//#include <bits/stdc++.h> //引用所有头文件,学习时慎用
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <bitset>
using namespace std;

const string base64_code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

//编码
string base64_encode(string plain_text)
{
	string base64_text, binary_text;

	//转为 8bit 二进制
	for(char i: plain_text)
		binary_text.append(bitset<8>(static_cast<int>(i)).to_string());
		
	//将长度补齐先到 6 的整数倍
	binary_text.append((6 - binary_text.length() %6) %6,'0');

	//按 6bit 为一组分割字符串并进行编码
	for (int i = 0, len = binary_text.length(); i < len; i += 6)
		base64_text += base64_code[stoi(binary_text.substr(i,6), nullptr, 2)];
		
	//在末尾加上 0~3 个=
	base64_text.append(((4 - binary_text.length() /6)) %4 %4,'=');
	return base64_text;
}

string base64_decode(string base64_text)
{
	string plain_text, binary_text;
	//转为 6bit 二进制
	for (auto i: base64_text)
		if (i!='=')
			binary_text.append(bitset<6>(base64_code.find(i)).to_string());
	
	//按 8bit 为一组分割字符串并进行解码
	for (int i = 0, len = binary_text.length()-binary_text.length()%8; i < len; i += 8)
		plain_text.push_back(static_cast<char>(stoi(binary_text.substr(i,8), nullptr, 2)));
	return plain_text;
}

int main()
{
    int num;
    string plain_text,cipher_text;
    cout << "请选择你要输入的类型的序号:\n1、加密\n2、解密\n----------\n输入序号:";
    cin >> num;cin.get();
    switch(num)
    {
        case 1:
            cout << "请输入:" << endl;
            getline(cin,plain_text);
            cout << "加密完成:\n" <<base64_encode(plain_text);
            break;
        case 2:
            cout << "请输入:" << endl;
            getline(cin,cipher_text);
            cout << "解密完成:\n" << base64_decode(cipher_text);
            break;
        default:
            cout << "输入错误" << endl;
            break;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Z时代.bug(゜▽゜*)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值