base64编码原理及代码实现

article/2025/9/13 6:21:03

在这里插入图片描述
在ctf里reverse经常会有base64相关的题型,每次写到这类题型只能凭经验猜测考点来解题,特此出一个base64相关的博客,加深对base64的理解,下次再看到伪代码也不会觉得慌了,毕竟纵使实现形式不同,代码的核心逻辑还是大差不差的。

base64编码原理及代码实现

  • 1. 简介
  • 2. 原理
    • 2.1 base64编码表
    • 2.2 当待编码数据正好为3的倍数时
      • 2.2.1 对abc进行base64编码
    • 2.3 当待编码数据不为3的倍数时
      • 2.3.1 对a进行base64编码
      • 2.3.2 对ab进行base64编码
    • 2.4 小结
  • 3. 代码实现
    • 3.1 其一
    • 3.2 其二

1. 简介

base64编码是一种以64个可打印字符来表示和传输数据的编码,通常base64编码的数据是没有含义的,base64编码后的数据要通过base64解码才有意义。

2. 原理

base64编码是由64(2^6)个可打印字符来表示的,占用6位,这6位数据正好从0到63对应64个字符,而1 byte = 8 bit,如何用6bit来表示1byte(8bit) 的数据呢,如果每3byte为一组,对应每4个base64编码数据,3 * 8 bit = 4 * 6 bit,这样就解决了这个问题。

2.1 base64编码表

索引和字符的对应关系被叫做base64编码表,如下图所示

base64编码表
索引字符
0A
1B
2C
3D
4E
5F
6G
7H
8I
9J
10K
11L
12M
13N
14O
15P
16Q
17R
18S
19T
20U
21V
22W
23X
24Y
25Z
26a
27b
28c
29d
30e
31f
32g
33h
34i
35j
36k
37l
38m
39n
40o
41p
42q
43r
44s
45t
46u
47v
48w
49x
50y
51z
520
531
542
553
564
575
586
597
608
619
62+
63/

2.2 当待编码数据正好为3的倍数时

2.2.1 对abc进行base64编码

以abc这个数据为例,对其进行base64编码,如下图所示,abc——>YWNE在这里插入图片描述
可以看到3字节的倍数的数据是可以完美适配base64编码的,但如果我想将非3字节倍数的数据进行base64编码呢?

2.3 当待编码数据不为3的倍数时

2.3.1 对a进行base64编码

a占一个字节(8 bit),而base64编码最少需要3 * 8 bit= 24 bit,因此需要在a后面再补2个空字符,这一组字符中,前6 bit的大小仍为24,对应的字符为Y,还剩下2 bit,则需要补0 直至补满6 bit,补满之后的数据大小为16,对应字符为Q,接下来的 2*6 bit = 12 bit 则填 2个 =,得到base64编码后的数据YQ
==,这样就解决了对一个字节进行base64编码的问题
在这里插入图片描述

2.3.2 对ab进行base64编码

ab共占二个字节(2 *8 bit = 16 bit),由上可知需要再补 1 byte达到 3 byte,对应的4个base64字符,其中,前两个分别为Y和Q,对于第三个,其前4bit是有数据的,而后2bit则需要补0,大小为8,对应字符为I,最后6 bit则用一个=来补齐。这样得到base64编码后的数据YWI=
在这里插入图片描述

2.4 小结

根据上面的个例,我们可以往数据量更大的情况考虑,假设一个数据有n byte(n > 3),如果 n % 3 = 0 ,则其base64编码后不存在=,因为它正好是 24 byte的倍数;如果n % 3 = 1,由于n = 3 * m + 1,3 * m 正好是24 byte的倍数,这部分不存在=,剩下最后 1 byte ,则按照上面2.3.1的步骤对其进行操作,后补 = =;如果n % 3 = 2,由于n = 3 * m + 2,3 * m 正好是24 byte的倍数,这部分不存在=,剩下最后 2 byte ,则按照上面2.3.2的步骤对其进行操作,后补 = 。

3. 代码实现

对于base64编码的代码,我这里学了两个版本,其中一个是在写ctf的reverse题时看到的,由于赛题是伪代码且逻辑不完整,所以我对其进行了完善,还有一个是我在学base64编码的时候看到的,其中第一个的代码量较小且更加利于理解,如果第一个的代码无法接受的也可以看看第二个,因人而异。
贴一下那道ctf的wp:
[WUSTCTF2020]level3

3.1 其一

#include<string.h>
#include<stdio.h>
#include<stdlib.h>
int main()
{char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";//data是代编码数据char data[] = "abcdefsdadasdsad2131324rfa2615";//data_len表示代编码数据能分成几组(3 * 8bit = 4 * 6 bit = 24bit)int data_len= strlen(data) / 3;//data_add表示分组后剩下几个int data_add = strlen(data) % 3;//开辟空间给src数组char *src = (char*)malloc(data_len * 4 + 4 + 1);//+4是为了给可能多的1或2个数据及后边要添的=留位置,+1是为了给'\0'留位置来表示字符串结尾int temp = 0;int tmp = 0;int n =0;//以4 * 6bit为单位将编码后的值传入srcwhile (temp < data_len){src[n++] = base64_table[data[tmp] >> 2];src[n++] = base64_table[16 * (data[tmp] & 0x3) | data[tmp + 1] >> 4];src[n++] = base64_table[4 * (data[tmp + 1] & 0xF) | data[tmp+ 2] >> 6];src[n++] = base64_table[data[tmp + 2] & 0x3F];tmp += 3;temp++;}//多出一个数据需要补2个=if(data_add == 1){src[n++] = base64_table[data[tmp] >> 2];src[n++] = base64_table[16 * (data[tmp] & 0x3)];src[n++] = '=';src[n++] = '=';src[n] = '\0';}//多出两个数据需要补1个=else if(data_add == 2){src[n++] = base64_table[data[tmp] >> 2];src[n++] = base64_table[(16 * (data[tmp] & 0x3)) | data[tmp + 1] >> 4];src[n++] = base64_table[4 * (data[tmp+1] & 0xF)];src[n++] = '=';src[n] = '\0';}else{src[n] = '\0';}printf("%s\n", src);
}

3.2 其二

#include<stdio.h>
#include<string.h>
#include<stdlib.h>const char base[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
static char find_pos(char ch);
char *base64_encode(const char* data, int data_len, int *len);
char *base_64decode(const char* data, int data_len, int *len);/***找到ch在base中的位置*/
static char find_pos(char ch)
{//the last position (the only) in base[]char *ptr = (char*)strrchr(base, ch);return (ptr - base);
}/***BASE64编码*/
char *base64_encode(const char* data, int data_len, int *len)
{int prepare = 0;int ret_len;*len = 0;int temp = 0;char *ret = NULL;char *f = NULL;int tmp = 0;char changed[4];int i =0;ret_len = data_len / 3;temp = data_len % 3;if(temp > 0){ret_len += 1;}//最后一位以'\0'结束ret_len = ret_len*4 + 1;ret = (char *)malloc(ret_len);if (ret == NULL){printf("No enough memory\n");exit(0);}memset(ret, 0, ret_len);f = ret;//tmp记录data中移动位置while (tmp < data_len){temp = 0;prepare = 0;memset(changed, 0, 4);while (temp < 3){if (tmp >= data_len){break;}//将data前8*3位移入prepare的低24位prepare = ((prepare << 8) | (data[tmp] & 0xFF));tmp ++;temp ++;}//将有效数据移到以prepare的第24位起始位置prepare = (prepare << ((3-temp) * 8));for (i = 0; i < 4; i++){//最后一位或两位if (temp < i){changed[i] = 0x40;}else{//24位数据changed[i] = (prepare >> ((3-i) * 6)) & 0x3F;}*f = base[changed[i]];f++;(*len)++;}}*f = '\0';return ret;
}//base64解码
char *base64_decode(const char *data, int data_len, int *len)
{int ret_len = (data_len / 4) * 3 + 1;int equal_count = 0;char *ret = NULL;char *f = NULL;*len = 0;int tmp = 0;int temp = 0;char need[3];int prepare = 0;int i =0;if (*(data + data_len - 1) == '='){equal_count += 1;}if (*(data + data_len -2) == '='){equal_count += 1;}ret = (char *)malloc(ret_len);if (ret == NULL){printf("No enough memory\n");exit(0);}memset(ret, 0, ret_len);f = ret;while (tmp < (data_len - equal_count)){temp = 0;prepare = 0;memset(need, 0, 4);while(temp < 4){if (tmp >= (data_len - equal_count)){break;}prepare = (prepare << 6) | (find_pos(data[tmp]));temp++;tmp++;}prepare = prepare << ((4-temp) * 6);for (i = 0; i< 3; i++){if (i == temp){break;}*f = (char)((prepare >> ((2-i) * 8)) & 0xFF);f++;(*len) ++;}}*f = ' ';if (data[data_len - 1] == '='){(*len)--;}return ret;
}
int main()
{
//在former里填入要编码的数据char *former ="a";int len1, len2;printf("%s\n", former);
//在第二个参数中填入要编码的数据的长度char *after = base64_encode(former, 1, &len1);printf("%d %s\n", len1, after);former = base64_decode(after, len1, &len2);printf("%d %s\n", len2, former);
}

http://chatgpt.dhexx.cn/article/n5qDaFRU.shtml

相关文章

Base64编码的原理与常用实现

这篇主要是为了后面好介绍加密算法&#xff0c;做的铺垫。 这个是基础&#xff0c;什么是一个程序员的涵养&#xff0c;这些基础就是涵养。 平时可能用不到&#xff0c;但必须得会。 如果连这个原理都说不上来&#xff0c;就别玩王者荣耀绝地求生英雄联盟和平精英了&#xff0c…

Base64原理及魔改更换码表

一&#xff0c;Base64是什么&#xff08;原理比较难理解&#xff0c;可参考下面的实践 &#xff09; Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64&#xff0c;所以每6个比特为一个单元&#xff0c;对应某个可打印字符。三个字节有24个比特…

base64加密原理解析

开发者对Base64编码肯定很熟悉&#xff0c;是否对它有很清晰的认识就不一定了。实际 上Base64已经简单到不能再简单了&#xff0c;如果对它的理解还是模棱两可实在不应该。大概介绍一下Base64的相关内容&#xff0c;花几分钟时间就可以彻底理解它。文 章下边贴了一个Base64的编…

Base64加密原理

Base64加密方式是将三个八位的字节转化为四个六位的字节&#xff08;不足八位的高位补00&#xff09;&#xff0c;3*8 4*6&#xff1b;&#xff0c;所以base64加密过后的内容比原来的大三分之一&#xff1b; 举例&#xff1a;加密“ace”&#xff0c; ace转化为二进制为&…

Base64编码原理分析

文章目录 一、认识&#xff08;一&#xff09;认识&#xff08;二&#xff09;计算&#xff08;1&#xff09;规则&#xff08;2&#xff09;示例&#xff08;3&#xff09;Base64编码转换表 二、网页图片转base64编码分析&#xff08;一&#xff09;Data URI&#xff08;二&am…

base64编码,原理是什么,有什么作用?

base64到底是什么东西呢&#xff1f; Base64编码是网络上常见的用于传输8bit字节数据的一种编码方式之一 , 有些人和书本会将编码写成加密算法&#xff0c;这其实是欠妥的。因为任何人拿到编码后的数据都能转化成原始数据&#xff0c;算法是透明的&#xff0c;也不存在秘钥的概…

一篇文章彻底掌握Base64编码原理

一篇文章彻底掌握Base64编码原理 在互联网中的每一刻&#xff0c;你可能都在享受着Base64带来的便捷&#xff0c;但对于Base64的基础原理又了解多少&#xff1f;今天这篇博文带领大家了解一下Base64的底层实现。 Base64的由来 目前Base64已经成为网络上常见的传输8Bit字节代…

Base64编码解码原理详解

Base64编码解码原理详解 1. Base64字符的组成部分 Base64所用字符&#xff1a; 0,1,2 ….9 A,B,C,D…Z a,b,c,d…z / 对应ASCII&#xff1a; 48,49…58,65,66…90,97,98…122, 43,47 2. 10个数字&#xff0c;26个大写字母&#xff0c;26个小写字母&#xff0c;1个&#xff0c…

彻底弄懂base64的编码与解码原理

作者介绍 背景 base64的编码原理网上讲解较多&#xff0c;但解码原理讲解较少&#xff0c;并且没有对其中的内部实现原理进行剖析。想要彻底了解base64的编码与解码原理&#xff0c;请耐心看完此文&#xff0c;你一定会有所收获。 涉及算法与逻辑运算概念 在探究base64编码原理…

深入理解 Base64 底层原理

Base64 是一种常见数据编码方式&#xff0c;常用于数据传输。对于移动开发者来讲&#xff0c;网络请求中会经常使用到。对 JSON 熟悉的同学都知道&#xff0c;JSON 的序列化工具都不支持将 byte 数组直接放入 JSON 数据中&#xff0c;针对这种二进制数据&#xff0c;在处理的时…

Base64基本原理

1.什么是Base64 Base64是一种基于64个可打印字符来表示二进制数据的编码方式&#xff0c;是从二进制数据到字符的过程。 原则上&#xff0c;计算机中所有内容都是二进制形式存储的&#xff0c;所以所有内容&#xff08;包括文本、影音、图片等&#xff09;都可以用base64来表示…

一篇文章彻底弄懂Base64编码原理

在互联网中的每一刻&#xff0c;你可能都在享受着Base64带来的便捷&#xff0c;但对于Base64的基础原理又了解多少&#xff1f;今天这篇博文带领大家了解一下Base64的底层实现。 Base64的由来 目前Base64已经成为网络上常见的传输8Bit字节代码的编码方式之一。在做支付系统时&…

Base64编码原理

一、Base64是什么 base 64、base 32、base 16 编码建议标准 https://www.ietf.org/rfc/rfc4648.txt Base64是基于64种字符的编码算法&#xff0c;即将数据使用64种字符表示&#xff0c;编码后的Base64字符串长度 通常为原来的3-4倍。&#xff08;补充&#xff1a;Base32就是…

Base64原理

前言 Base64是什么?它和加解密操作有什么关系吗?我们看一下下边这段字符串: aGVsbG8gd29ybGQ= 这就是经过Base64编码后的字符串,对它进行Base64解码,获得它原来的内容: hello world 这有点加密解密的意味,不过Base64并不能称为加密算法,仅仅是加密算法的近亲,可以称之…

Base64原理解析

一. Base64编码由来 为什么会有Base64编码呢&#xff1f;因为有些网络传送渠道并不支持所有的字节&#xff0c;例如传统的邮件只支持可见字符的传送&#xff0c;像ASCII码的控制字符就 不能通过邮件传送。这样用途就受到了很大的限制&#xff0c;比如图片二进制流的每个字节不可…

base64加密原理详解

Base64编码&#xff0c;是我们程序开发中经常使用到的编码方法。它是一种基于用64个可打印字符来表示二进制数据的表示方法。它通常用作存储、传输一些二进制数据编码方法&#xff01;也是MIME&#xff08;多用途互联网邮件扩展&#xff0c;主要用作电子邮件标准&#xff09;中…

Base64基本原理及简单应用

1.什么是Base64 Base64是一种基于64个可打印字符来表示二进制数据的编码方式,是从二进制数据到字符的过程。原则上,计算机中所有内容都是二进制形式存储的,所以所有内容(包括文本、影音、图片等)都可以用base64来表示。 2.Base64编码原理 Base64编码之所以称为Base64,是因…

一文详解 Base64编码原理

最近在看Android的签名与验签机制&#xff0c;其中涉及到 MD5、SHA2、SHA256 等摘要算法&#xff0c;也涉及到 Base64 编码机制。这里先从简单的入手&#xff0c;记录一下 Base64 编码机制的原理。 一、Base64由来 Base64 是一种编码方式&#xff0c;最早出现在电子邮件传输协…

在Unity中导入fbx格式文件

unity中是以米为单位&#xff0c;要想让3dmax中建的模型导入到unity中与unity自带的3d object尺寸一致&#xff0c;最直接的办法是将3dmax中的系统单位也设成米。在三维软件里设置 在菜单->自定义->单位设置&#xff1a; 导出FBX文件前 &#xff0c;我们需要注意如下问…

读取FBX文件踩坑清单

FBX文件得到了许多3D制图软件与3D游戏引擎的兼容&#xff0c;其发展趋势大好。因此若要编写一款3D图形系统&#xff0c;对FBX格式的支持是必经之路&#xff08;或者使用插件形式&#xff09;。笔者尝试在百度、必应等搜索引擎&#xff0c;外加fbxsdk实例的帮助下&#xff0c;读…