【算法浅析NO.00003】浅析base64编码算法的加密与解密:打造属于自己的“base64”! by arttnba3

本文深入解析Base64编码原理,包括密钥、转换规则、非3倍数字节的处理。介绍了加密和解密的C++代码实现,并探讨了如何自定义密钥,以及在moeCTF2019中遇到的Base64挑战问题。
摘要由CSDN通过智能技术生成

绪论

天下编码规则千千万,而base64则是网络上使用的最为广泛的一种用于传输8Bit字节的编码方式之一,Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读

而正巧这几天做moeCTF的时候有一道题涉及到了base64,所以今天我想写一篇博文来讲讲究竟什么是base64

豆知识:其实一般我都是断断续续几天写完一篇的…

基本原理

加密

一、密钥

正所谓“?如其名”,base64编码的加密过程正是基于一个64位的密钥进行的,转换的对应规则如下表:

原值 转换所得字符 原值 转换所得字符 原值 转换所得字符 原值 转换所得字符
0 A 16 Q 32 g 48 w
1 B 17 R 33 h 49 x
2 C 18 S 34 i 50 y
3 D 19 T 35 j 51 z
4 E 20 U 36 k 52 0
5 F 21 V 37 l 53 1
6 G 22 W 38 m 54 2
7 H 23 X 39 n 55 3
8 I 24 Y 40 o 56 4
9 J 25 Z 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /

利用字符数组我们可以很好的表示出密钥,通过改变密钥我们则可以打造一套属于自己的“base64”:

char key_form[64]={
   0};
...
int main(void)
{
   
...
	ifstream key_in;
	key_in.open("key.txt",ios::in);
	char ch;
	for(int i=0;i<64;i++)
		key_in>>key_form[i];

也许没了解过base64的朋友会对转化表感觉很疑惑,哪怕是最基础的ASCII都是有128个字符,那么这只有64个对应关系的密钥真的够用吗?

但是相信不少人在看到64的时候便已经有一定的想法了:

64=26(base64密钥)
128=28 (ASCII)

你想到了什么呢?

二、转换规则:“三变四,按表转”

我们都知道,通常在计算机当中储存的字符,一个字符(char)要占用一个字节(byte),即8个二进制位(bit)

豆知识:汉字编码一般根据GB2312-80标准进行,一个汉字占两个字节

比如说字符’A’,她的ASCII码是65,即在内存当中储存的字符为’A’的变量实际的值为65,她在内存里长这个样子:

文本 A
ASCII码 65
二进制位 0 1 0 0 0 0 0 1

豆知识:在CSDN上画表格是一件十分麻烦且艹蛋的事情

我们以三个字符"ABC"作为例子:

文本 A B C
ASCII码 65 66 67
0 1 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1

(上面空的格仅在本文中用作表示分隔,在内存中并不存在)

我们以每三个字符作为一组,一共24个二进制位,重新进行分组

重新分组时我们以每6个二进制位作为一组,共分为四组:
0 1 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1
最后在每组的高位补上两个0,变成标准的一个字节:
0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 1

于是转化后内存当中的值变为了:

16 20 9 3

转换后呢?我们直接将这个值进行输出吗?这四个字符都是特殊类型字符,又如何在文本当中输出呢?

别忘了我们还有密码表啊,base64之所以叫base64可不就是因为有一份64个对应关系的密码表么?

我们将这些值按照密码表上的对应关系进行转换,最终输出的文本应该是:

Q U J D

相信大家看到这里也应该明白为什么密钥是有着64个对应关系的了,六位的一个无符号整型所能表示的数据范围不就是0~63、刚好是64个数么?

三、非3倍数字节文本:“尾补0,余补=”

或许有的人要问:如果字节数并不是三个字节,该如何进行编码呢?

无论是剩余一个字节,还是剩余两个字节,都无法满足基础的base64编码的要求

base64编码标准对于这种特殊情况的处理标准是:

对于多余的一个字符,在末尾补上4个0,使其能被分为两个6位的量,并在最终输出的文本当中补充两个’='字符
对于多余的两个字符,在末尾补上2个0,使其能被分为三个6位的量,并在最终输出的文本当中补充一个’='字符

如下图所示(图片来自网络,如有侵权请第一时间联系我):
在这里插入图片描述

四、代码实现

base64加密最终的C++代码实现如下:


void base_64(void)
{
   
	char ch;
	for(i=0;(ch=getchar())!=EOF;i+=8)//此处使用freopen()函数进行重定向以从文件中读取,若是从标准输入流读取一行字符串的话也可以把判定条件变为'\n'而不是EOF
	{
   
		for(j=7;j>=0;j--)//转换为二进制进行运算
		{
   
			plaintext[i+j]=ch&1;
			ch>>=1;
		}
	
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值