首页 > 其他分享 >What-is-base64-code

What-is-base64-code

时间:2024-06-12 21:59:29浏览次数:25  
标签:What base64 ++ Base64 length code encoded data

Base64 编码和解码

Base64是一种基于64个可打印字符来表示二进制数据的编码方式。它通常用于在文本数据中传输二进制数据,例如电子邮件和URL。

Base64编码过程

  1. 数据分割:将输入的二进制数据按每24位(3字节)一组分割。如果最后一组不足24位,用0进行填充。
  2. 每6位一组:将每24位的数据再分割成4个6位的数据块。
  3. 映射到字符:每个6位的数据块对应一个Base64字符。Base64字符表包含A-Z、a-z、0-9、+和/,共64个字符。
  4. 填充字符:如果输入数据长度不是3的倍数,输出会填充一个或两个'='字符,使其长度为4的倍数。

Base64解码过程

  1. 去除填充:将输入的Base64字符串中的'='去除。
  2. 映射到二进制:将每个Base64字符映射回6位二进制数据。
  3. 合并数据块:将6位的数据块按顺序合并成原始的8位数据块。
  4. 移除填充位:去除由于编码时填充的0位,恢复原始数据。

代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

// Base64字符表
const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

// Base64字符反向映射表
static const int base64_chars_inverse[] = {
    // ASCII值到Base64索引的映射
    [43] = 62, [47] = 63, [48] = 52, [49] = 53, [50] = 54, [51] = 55,
    [52] = 56, [53] = 57, [54] = 58, [55] = 59, [56] = 60, [57] = 61,
    [65] = 0,  [66] = 1,  [67] = 2,  [68] = 3,  [69] = 4,  [70] = 5,
    [71] = 6,  [72] = 7,  [73] = 8,  [74] = 9,  [75] = 10, [76] = 11,
    [77] = 12, [78] = 13, [79] = 14, [80] = 15, [81] = 16, [82] = 17,
    [83] = 18, [84] = 19, [85] = 20, [86] = 21, [87] = 22, [88] = 23,
    [89] = 24, [90] = 25, [97] = 26, [98] = 27, [99] = 28, [100] = 29,
    [101] = 30, [102] = 31, [103] = 32, [104] = 33, [105] = 34, [106] = 35,
    [107] = 36, [108] = 37, [109] = 38, [110] = 39, [111] = 40, [112] = 41,
    [113] = 42, [114] = 43, [115] = 44, [116] = 45, [117] = 46, [118] = 47,
    [119] = 48, [120] = 49, [121] = 50, [122] = 51
};

// Base64编码函数
char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length) {
    // 计算输出长度,Base64编码后的长度是输入长度的4/3并向上取整
    *output_length = 4 * ((input_length + 2) / 3);
    char *encoded_data = malloc(*output_length + 1); // 分配内存
    if (encoded_data == NULL) return NULL;

    // 遍历输入数据,按每3字节一组进行处理
    for (size_t i = 0, j = 0; i < input_length;) {
        // 三个字节一组,输入长度非3的倍数,需要在组内末尾补0
        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;

        // 合并三个字节为24位
        // octet_a << 0x10:将 octet_a 左移16位,即将 octet_a 放在24位数的高8位。
        // octet_b << 0x08:将 octet_b 左移8位,即将 octet_b 放在24位数的中间8位。
        // octet_c:保持 octet_c 在最低8位。
        uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;

        // 分别取出高6位、中6位和低6位,并根据Base64字符表进行转换
        // triple 右移18位(即 3 * 6),取最低6位,在通过Base64字符表进行转换
        encoded_data[j++] = base64_chars[(triple >> 3 * 6) & 0x3F];  
        encoded_data[j++] = base64_chars[(triple >> 2 * 6) & 0x3F];
        encoded_data[j++] = base64_chars[(triple >> 1 * 6) & 0x3F];
        encoded_data[j++] = base64_chars[(triple >> 0 * 6) & 0x3F];
    }

    // 添加填充字符
    static const int mod_table[] = {0, 2, 1};
    for (size_t i = 0; i < mod_table[input_length % 3]; ++i)
        encoded_data[*output_length - 1 - i] = '=';

    // 添加字符串结束符
    encoded_data[*output_length] = '\0';
    return encoded_data;
}

// Base64解码函数
unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length) {
    if (input_length % 4 != 0) return NULL; // Base64输入长度必须是4的倍数

    // 计算输出长度
    *output_length = input_length / 4 * 3;
    if (data[input_length - 1] == '=') (*output_length)--;
    if (data[input_length - 2] == '=') (*output_length)--;

    unsigned char *decoded_data = malloc(*output_length); // 分配内存
    if (decoded_data == NULL) return NULL;

    // 遍历输入数据,按每4字符一组进行处理
    for (size_t i = 0, j = 0; i < input_length;) {
        // 检查当前字符是否是 ‘=’
        // 如果是 =,则结果为0(由于按位与运算与 0 的结果总是 0),并且 i 递增
        // 如果不是 =,则查找 data[i] 在 base64_chars_inverse 表中的映射值,并且 i 递增。
        uint32_t sextet_a = data[i] == '=' ? 0 & i++ : base64_chars_inverse[data[i++]];
        uint32_t sextet_b = data[i] == '=' ? 0 & i++ : base64_chars_inverse[data[i++]];
        uint32_t sextet_c = data[i] == '=' ? 0 & i++ : base64_chars_inverse[data[i++]];
        uint32_t sextet_d = data[i] == '=' ? 0 & i++ : base64_chars_inverse[data[i++]];

        // 合并4个6位数为24位
        uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) + (sextet_c << 1 * 6) + (sextet_d << 0 * 6);

        // 分别取出高8位、中8位和低8位
        // 将 triple 右移16位(即 2 * 6),取最低8位,在通过base64_chars_inverse字符表进行转换
        if (j < *output_length) decoded_data[j++] = (triple >> 2 * 8) & 0xFF; 
        if (j < *output_length) decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
        if (j < *output_length) decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
    }

    return decoded_data;
}

示例程序


int main() {
    // 示例数据
    const char *data = "Hello, world!";
    size_t data_length = strlen(data);

    // Base64编码
    size_t encoded_length;
    char *encoded_data = base64_encode((const unsigned char *)data, data_length, &encoded_length);
    if (encoded_data == NULL) {
        fprintf(stderr, "Failed to encode data to Base64\n");
        return 1;
    }
    printf("Base64 Encoded: %s\n", encoded_data);

    // Base64解码
    size_t decoded_length;
    unsigned char *decoded_data = base64_decode(encoded_data, encoded_length, &decoded_length);
    if (decoded_data == NULL) {
        fprintf(stderr, "Failed to decode Base64 data\n");
        free(encoded_data);
        return 1;
    }
    printf("Base64 Decoded: %.*s\n", (int)decoded_length, decoded_data);

    // 清理内存
    free(encoded_data);
    free(decoded_data);

    return 0;
}

标签:What,base64,++,Base64,length,code,encoded,data
From: https://www.cnblogs.com/LeanderPeng/p/18244788

相关文章

  • Base64编码解码流程的初步学习
    目录什么是Base64编码?为什么要学习Base64编码?Base64编码基础原理介绍Base64编码组成Base64编码索引表Base64编码规则Base64编码过程简记编码流程实战Base64编码(不同情况举例说明)1.待编码字符数量为3的倍数2.待编码字符数量不为3的倍数Base64解码原理简单介绍Base64解码过程Base6......
  • 创建entity模板,equals hashcode 方法模板
    创建entity模板,equalshashcode方法模板如下为FLINK官网实体类demoequalshashcode方法模板可以参考////Sourcecoderecreatedfroma.classfilebyIntelliJIDEA//(poweredbyFernFlowerdecompiler)//packageorg.apache.flink.walkthrough.common.entity;im......
  • CodeArts Snap 华为云智能开发助手
    CodeArtsSnap是华为云推出的一款基于大模型技术的智能开发助手,旨在提高开发人员的生产力和代码质量,为开发者带来全新的编程方式和体验。优势:八大核心功能:CodeArtsSnap提供单元测试用例生成、代码生成、代码解释、代码调试、研发知识问答、代码注释、代码检查和代码翻译等......
  • VSCode安装使用教程,保姆级!
    前言VisualStudioCode(简称VSCode)是一款由微软开发的免费、开源的轻量级代码编辑器,它支持多种编程语言和平台,并提供丰富的扩展功能,让开发者能够更高效地编写代码。本文将向您介绍如何安装和使用VSCode,以及一些常用的功能和技巧。VSCode下载、安装我们可以直接在官网下载......
  • (nice!!!)LeetCode 2865. 美丽塔 I(数组、单调栈)
    2865.美丽塔I思路:方法一,时间复杂度0(n^2)。枚举每一个点i作为当前山脉数组的最高点。然后我们通过预处理遍历其前面和后面,来更新两个数组f1、f2。数组f1[i]:表示在满足非递减的情况下,区间0~i,以点i的高度heighs[i]为最高点所能形成的最大高度和。数组f2[i]:表示在满足非......
  • codelity
    source:https://app.codility.com/programmers/trainings/5/three_letters/classSolution{publicstringsolution(intA,intB){//ImplementyoursolutionhereStringBuilderstr=newStringBuilder();if(A>B){......
  • FileCodeBox --一个文件快递柜
    介绍什么是FileCodeBox?以下内容摘至Github:匿名口令分享文本,文件,像拿快递一样取文件它的特点有什么?以下内容摘至Github:轻量简洁:Fastapi+Sqlite3+Vue2+ElementUI轻松上传:复制粘贴,拖拽选择多种类型:文本,文件防止爆破:错误次数限制防止滥用:IP限制上传次数口令分享:......
  • 云效codeup
    云效codeup什么是云效codeup云效codeup操作代码库代码托管代码检测代码提交代码评审代码迁移使用感受及建议什么是云效codeup云效代码管理(Codeup)是阿里云云效一站式BizDevOps平台提供的自研代码管理服务,为企业提供代码托管、代码评审、代码检测、代码搜索等服务,全......
  • LeetCode 300. 最长递增子序列
    更多题解尽在https://sugar.matrixlab.dev/algorithm每日更新。组队打卡,更多解法等你一起来参与哦!LeetCode300.最长递增子序列,难度中等。动态规划解题思路:遍历数组,对于每个nums[i],检查其之前的所有元素nums[j]0......
  • LeetCode刷题之HOT100之单词搜索
    2024/6/12这两天天气只能用闷、潮、热来描述。整个人像被罩在为了饭菜保温的盖子里,喘气困难、粘稠的空气一次又一次打湿我。唯有空调救我,夏天来了。Anyway,昨天只做了一题,今天早点来做一题。1、题目描述2、逻辑分析给定一个二维字符矩阵和一个单词,求单词是否在这个二维......