用于将字节进行base64编码或解码(C语言实现)

打印 上一主题 下一主题

主题 914|帖子 914|积分 2742

V1.0 2024年6月13日 发布于博客园

目次

基本原理见代码注释!
base64.h
  1. #ifndef _BASE64_H
  2. #define _BASE64_H
  3. /**
  4. * @file name : base64.h
  5. * @brief     : 用于将字节进行base64编码或解码
  6. * @author    : RISE_AND_GRIND@163.com
  7. * @date      : 2024年6月12日
  8. * @version   : 1.0
  9. * @note      :
  10. * CopyRight (c)  2023-2024   RISE_AND_GRIND@163.com   All Right Reseverd
  11. */
  12. /**Base64基本介绍
  13. *  什么是Base64编码?
  14. *      编码的主要目的是在需要通过文本传输或存储二进制数据的场景中,
  15. *      确保数据的完整性和可读性。直接使用ASCII存储二进制数据存在一些问题,
  16. *      因为二进制数据可能包含不可打印字符或特殊字符,这些字符在某些传输媒介(如电子邮件、URL等)中可能会被误解或破坏。
  17. *  为什么要使用Base64?
  18. *      可读性和可传输性:
  19. *          Base64编码将二进制数据转换为可打印的ASCII字符,确保数据在传输过程中不被改变。
  20. *          许多传输协议(如SMTP邮件协议)只支持文本数据,Base64编码使得二进制数据可以通过这些协议传输。
  21. *
  22. *      避免数据损坏:
  23. *          某些传输通道可能会对非文本数据进行处理或修改,Base64编码可以避免这些问题。
  24. *
  25. *      兼容性:
  26. *          Base64编码后的数据可以在不同系统和平台之间无缝传输,而不会受到字符集或编码方式的影响。
  27. *
  28. *  Base64的应用:电子邮件附件、Web数据传输(图片、文件等)、数据存储(某些数据库)、加密和签名
  29. */
  30. /**Base64基本原理
  31. * Base64(64个字符) -->2^6即6个比特-->其字符编码范围为0~63
  32. * -->"A-Z" "a-z" "0~9" "+" "/"
  33. * -->'A-Z' -- 编码范围 0~25
  34. * -->'a-z' -- 编码范围 26~51
  35. * -->'0-9' -- 编码范围 52~61
  36. * -->'+'   -- 编码范围 62
  37. * -->'/'   -- 编码范围 63
  38. *
  39. * 注意, 最后不足4字符会以'='补齐
  40. *
  41. * 例如: 将ASCII码的"Man"转换为Base64编码为TWFu
  42. *  M---->ASCII对应值: A(65)+12 = 77  --->十六进制:0x4D--->二进制:0100 1101
  43. *  a---->ASCII对应值: a(97)+0  = 97  --->十六进制:0x61--->二进制:0110 0001
  44. *  n---->ASCII对应值: a(97)+13 = 110 --->十六进制:0x6E--->二进制:0110 1110
  45. *
  46. *  在内存中(ASCII)        :0100 1101 0110 0001 0110 1110
  47. *  6位划分为Base64        :  010011|  010110|  000101|  101110
  48. *  但内存是以字节为单位    :00010011|00010110|00000101|00101110
  49. *  Base64显示             : T(19)   W(22)   F(5)     u(46)
  50. *
  51. *  所以每3个字节ASCII码会生成4个字节的Base编码
  52. */
  53. /***************************************头文件***************************************/
  54. #include <stdio.h>
  55. #include <string.h>
  56. /***************************************END******************************************/
  57. // 查找Base64字符在表中的位置, 进行数值还原
  58. int base64_char_value(char c);
  59. /**将字符串进行Base64编码
  60. * @name      base64_encode
  61. * @brief     将字符串进行Base64编码
  62. * @param     input 输入的ASCII字符串
  63. * @param     output  得到的base64编码
  64. * @date      2024年6月12日
  65. * @version   1.0
  66. * @note
  67. */
  68. void base64_encode(const unsigned char *input, char *output);
  69. /**将字符串进行Base64解码
  70. * @name      base64_decode
  71. * @brief     将字符串进行Base64解码
  72. * @param     input 输入的base64编码
  73. * @param     output  得到的ASCII字符串
  74. * @date      2024年6月12日
  75. * @version   1.0
  76. * @note
  77. */
  78. void base64_decode(const char *input, unsigned char *output);
  79. #endif
复制代码
base64.c

[code]/** * @file name : base64.c * @brief     : 用于将字节进行base64编码或解码 * @author    : RISE_AND_GRIND@163.com * @date      : 2024年6月12日 * @version   : 1.0 * @note      : * CopyRight (c)  2023-2024   RISE_AND_GRIND@163.com   All Right Reseverd */#include "../../include/utilities/base64.h"// Base64字符表, 用于编码息争码 static限制为文件域static const char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";// 查找Base64字符在表中的位置, 进行数值还原int base64_char_value(char c){    if (c >= 'A' && c = 'a' && c = '0' && c > 2;                           // a3[0] & 11111100 取a3[0]的前6位            a4[1] = ((a3[0] & 0x03) > 4); // 取a3[0]的后2位和a3[1]的前4位            a4[2] = ((a3[1] & 0x0f) > 6); // 取a3[1]的后4位和a3[2]的前2位            a4[3] = a3[2] & 0x3f;                                  // 取a3[2]的后6位            for (i = 0; i < 4; i++) // 每次输出4个编码后的字符            {                *output++ = base64_table[a4]; // 将编码后的Base64值映射到Base64字符表, 转换为ASCII码的形式体现(只是体现, 内容是Base64)            }            i = 0; // 重置计数器        }    }    if (i) // 若位数不敷3个字节    {        for (j = i; j < 3; j++) // 用0填充不敷的字节部门        {            a3[j] = '\0';        }        // 同上利用        a4[0] = (a3[0] & 0xfc) >> 2;        a4[1] = ((a3[0] & 0x03) > 4);        a4[2] = ((a3[1] & 0x0f) > 6);        a4[3] = a3[2] & 0x3f;        // 将已编码好的部门输出, +1是因为若只有一个字节也至少生成2个字符, 始终会+1        for (j = 0; j < (i + 1); j++)        {            *output++ = base64_table[a4[j]];        }        while ((i++ < 3))        {            *output++ = '='; // 用'='填充不敷的部门并输出        }    }    *output = '\0'; // 输出字符串完毕}/**将字符串进行Base64解码 * @name      base64_decode * @brief     将字符串进行Base64解码 * @param     input 输入的base64编码 * @param     output  得到的ASCII字符串 * @date      2024年6月12日 * @version   1.0 * @note */void base64_decode(const char *input, unsigned char *output){    int i = 0; // 计数器    int j = 0;    unsigned char a4[4] = {0}; // 每次输入4个Base64字符缓冲区    unsigned char a3[3] = {0}; // 每次输出3个ASCII码字节缓冲区, 4个Base64编码可生成3个ASCII码    while (*input)    {        for (i = 0; i < 4; i++) // 以4个base字符为单位进行处理        {            if (*input == '=') // 若是末尾            {                a4 = 0; // 转换为'\0'            }            else // 若不是末尾            {                a4 = base64_char_value(*input);            }            input++; // 继续读入1个字符        }        a3[0] = (a4[0] > 4);          // 解码第一个字节 取消移位        a3[1] = ((a4[1] & 0x0f) > 2); // 解码第二个字节        a3[2] = ((a4[2] & 0x03)
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

麻花痒

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表