欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > CTF-RE 从0到N 1-3 理解base64算法

CTF-RE 从0到N 1-3 理解base64算法

2024/10/25 15:24:48 来源:https://blog.csdn.net/weixin_59166557/article/details/143233164  浏览:    关键词:CTF-RE 从0到N 1-3 理解base64算法

Base64是一种常用的编码方式,用于将二进制数据转换为文本格式。它常用于在需要通过文本传输二进制数据的场景中,例如在电子邮件和URL中传递二进制文件。Base64的核心原理如下:

原理

  1. 输入数据分组

    • 将输入的二进制数据按字节分成每组3字节(24位)。
  2. 转换为6位块

    • 将每3字节(24位)的数据块分成4个6位块。这样,每个6位块可以表示一个范围在0到63之间的整数。
  3. 映射到Base64字符集

    • 使用Base64字符表将每个6位块映射到一个Base64字符。Base64字符集包含64个字符,包括大写字母A-Z,小写字母a-z,数字0-9,以及两个特殊字符“+”和“/”。
  4. 处理不足3字节的数据

    • 如果最后一组数据不足3字节,则用0字节填充,以保证数据长度是3的倍数。编码后,用一个或两个等号(=)填充,以表明原始数据的长度。

Base64字符表

Base64字符表如下:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

示例

假设我们要编码字符串"Man"。

  1. 输入数据

    • 字符串"Man"的ASCII码是:
      M: 77 (01001101)
      a: 97 (01100001)
      n: 110 (01101110)
      
    • 合并成二进制数据:
      01001101 01100001 01101110
      
  2. 分成6位块

    • 划分后得到:
      010011 010110 000101 101110
      
  3. 转换为十进制

    • 每个6位块对应的整数是:
      19 22 5 46
      
  4. 映射到Base64字符集

    • 使用Base64字符表对应的字符是:
      T W F u
      

因此,字符串"Man"被Base64编码后就是"TWFu"。

处理不足3字节的数据

假设我们要编码字符串"Ma"。

  1. 输入数据

    • 字符串"Ma"的ASCII码是:
      M: 77 (01001101)
      a: 97 (01100001)
      
  2. 补齐到3字节

    • 补齐后变成:
      01001101 01100001 00000000
      
  3. 分成6位块

    • 划分后得到:
      010011 010110 000100 000000
      
  4. 转换为十进制

    • 每个6位块对应的整数是:
      19 22 16 0
      
  5. 映射到Base64字符集

    • 使用Base64字符表对应的字符是:
      T W Q A
      
  6. 添加填充字符

    • 因为原始数据不足3字节,我们在末尾添加一个等号(=),表示有1字节填充。
    • 最终结果是:
      TWFu==
      

解码过程

解码过程与编码过程相反,分以下几步:

  1. 移除填充字符

    • 移除结尾的等号(=)。
  2. 转换Base64字符为6位块

    • 将每个Base64字符转换回对应的6位二进制块。
  3. 重新组合为8位块

    • 将6位块重新组合成8位块。
  4. 转换为原始字节

    • 将8位块转回原始的字节数据。

通过这些步骤,Base64编码和解码可以在文本和二进制数据之间无损转换。

读懂这段代码!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// Base64编码表
static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ""abcdefghijklmnopqrstuvwxyz""0123456789+/";// 判断字符是否为Base64编码字符
int is_base64(unsigned char c) {return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '+') || (c == '/');
}// Base64编码函数
char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length) {// 计算编码后的字符串长度*output_length = 4 * ((input_length + 2) / 3);// 为输出字符串分配内存char *encoded_data = (char *)malloc(*output_length + 1);if (encoded_data == NULL) return NULL;// 编码过程for (size_t i = 0, j = 0; i < input_length;) {uint32_t octet_a = i < input_length ? data[i++] : 0;uint32_t octet_b = i < input_length ? data[i++] : 0;uint32_t octet_c = i < input_length ? data[i++] : 0;uint32_t triple = (octet_a << 16) | (octet_b << 8) | octet_c;encoded_data[j++] = base64_chars[(triple >> 18) & 0x3F];encoded_data[j++] = base64_chars[(triple >> 12) & 0x3F];encoded_data[j++] = base64_chars[(triple >> 6) & 0x3F];encoded_data[j++] = base64_chars[triple & 0x3F];}// 添加填充字符for (size_t i = 0; i < (3 - input_length % 3) % 3; i++) {encoded_data[*output_length - 1 - i] = '=';}// 添加字符串终止符encoded_data[*output_length] = '\0';return encoded_data;
}// 测试函数
int main() {const char *text = "Hello, World!";size_t input_length = strlen(text);size_t output_length;// Base64编码char *encoded_text = base64_encode((const unsigned char *)text, input_length, &output_length);if (encoded_text == NULL) {fprintf(stderr, "内存分配失败\n");return 1;}// 输出编码后的字符串printf("Base64编码后的结果:%s\n", encoded_text);// 释放内存free(encoded_text);return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com