前两天在做一个项目时,合作方的开发人员说需要用到Base64 编码。由于之前没听说过这种编码,马上上网google 了下资料,才发现Base64 编码使用得这么普遍,最常用的就是电子邮件传输编码方式。进一步查找资料发现,迅雷的下载地址链接也使用这种编码方式。

引用维基百科中对Base64 编码的介绍如下:

“在MIME 格式的电子邮件中,base64 可以用来将binary 的字节序列数据编码成ASCII 字符序列构成的文本。使用时,在传输编码方式中指定base64 。使用的字符包括大小写字母各26 个,加上 10 个数字,和加号「+ 」,斜杠「 / 」,一共 64 个字符,等号「= 」用来作为后缀用途。

完整的base64 定义可见  RFC 1421和  RFC 2045。编码后的数据比原始数据略长,为原来的4/3 。在电子邮件中,根据RFC 822规定,每76 个字符,还需要加上一个回车换行。可以估算编码后数据长度大约为原长的135.1% 。

转换的时候,将三个byte 的数据,先后放入一个24bit 的缓冲区中,先来的byte 占高位。数据不足3byte 的话,于缓冲区中剩下的bit 用 0 补足。然后,每次取出6 (因为 26 = 64 )个bit ,按照其值选择ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ 中的字符作为编码后的输出。不断进行,直到全部输入数据转换完成。如果最后剩下两个输入数据,在编码结果后加 1 个「 = 」;如果最后剩下一个输入数据,编码结果后加2 个「 = 」;如果没有剩下任何数据,就什么都不要加,这样才可以保证数据还

原的正确性。”

知道了编码的原理后,又上网搜索了有没开源的lib 可用,发现网站libb64: Base64 Encoding/Decoding Routines下已有完整的编码/ 解码源代码可用,下载下来对某一通过Base64 编码的字串进行解码,顺利通过了。试了下编码的功能,发现编码得到的字串在末尾总与标准有差异,查看了源代码,发现其编码并没有按照标准进行。

于是,马上冒出了自己重写Base64 编码的C 语言代码的念头(后来索性把解码也重新实现了一遍),就当是巩固移位运算的操作吧。虽然编码/ 解码的原理比较简单,但实现完了还是比较开心的,下面把自己实现的编码/ 解码的代码贴出来:

// file: base64_encode.c
const int CHARS_PER_LINE = 76;
int base64_encode(unsigned char *src, long len, char *dest)
{const char *encode_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";char *ori_dest = dest;int i = 0, step_count = 0;int n, r;while (i + 3 <= len){n = *(src + i) << 16;n |= *(src + i + 1) << 8;n |= *(src + i + 2);*(dest++) = encode_table[(n & 0x00FC0000) >> 18];*(dest++) = encode_table[(n & 0x0003F000) >> 12];*(dest++) = encode_table[(n & 0x00000FC0) >> 6];*(dest++) = encode_table[(n & 0x0000003F)];if (++step_count == CHARS_PER_LINE / 4){step_count = 0;*(dest++) = '/n';}i += 3;}if (r = len % 3){if (r == 1){n = *(src + i) << 16;*(dest++) = encode_table[(n & 0x00FC0000) >> 18];*(dest++) = encode_table[(n & 0x0003F000) >> 12];*(dest++) = '=';*(dest++) = '=';}if (r == 2){n = *(src + i) << 16;n |= *(src + i + 1) << 8;*(dest++) = encode_table[(n & 0x00FC0000) >> 18];*(dest++) = encode_table[(n & 0x0003F000) >> 12];*(dest++) = encode_table[(n & 0x00000FC0) >> 6];*(dest++) = '=';}if (++step_count == CHARS_PER_LINE / 4){*(dest++) = '/n';}}*dest = '/0';return dest - ori_dest;
}
// file: base64_decode.c
#include <string.h>
#include <ctype.h>
static long check_length(char *src)
{char *p = strchr(src, '=');if (p == NULL)return strlen(src);elsereturn p - src;
}
static char base64_decode_digit(char ch)
{switch (ch){case '+':return 62;case '/':return 63;default:if (isdigit(ch))return ch - '0' + 52;else if (islower(ch))return ch - 'a' + 26;else if (isupper(ch))return ch - 'A';}return 0xFF;
}
int base64_decode(char *src, unsigned char *dest)
{int i = 0, n, r;long len;unsigned char *ori_dest = dest;len = check_length(src);while (i + 4 <= len){n = base64_decode_digit(*(src + i)) << 18;n |= base64_decode_digit(*(src + i + 1)) << 12;n |= base64_decode_digit(*(src + i + 2)) << 6;n |= base64_decode_digit(*(src + i + 3));*(dest++) = n >> 16;*(dest++) = (n >> 8) & 0xFF;*(dest++) = n & 0xFF;if (*(src + i + 4) == '/n')i++;i += 4;}if (r = len % 4){if (r == 2){n = base64_decode_digit(*(src + i)) << 18;n |= base64_decode_digit(*(src + i + 1)) << 12;*(dest++) = n >> 16;}if (r == 3){n = base64_decode_digit(*(src + i)) << 18;n |= base64_decode_digit(*(src + i + 1)) << 12;n |= base64_decode_digit(*(src + i + 2)) << 6;*(dest++) = n >> 16;*(dest++) = (n >> 8) & 0xFF;}}*dest = '/0';return dest - ori_dest;
}

用C语言实现编码/解码的功能后,对任意一字串进行编码后与网站(站长工具)https://tool.chinaz.com/Tools/Base64.aspx(一个在线测试Base64编码的网站)下编码的结果进行比较,发现是一样的。又对编码后的字串进行解码,也顺利还原了:)

Base64编码/解码原理及实现相关推荐

  1. Base64编码解码原理详解

    Base64编码解码原理详解 1. Base64字符的组成部分 Base64所用字符: 0,1,2 -.9 A,B,C,D-Z a,b,c,d-z + / 对应ASCII: 48,49-58,65,6 ...

  2. Base64编码解码原理

    一. Base64编码由来 为什么会有Base64编码呢?因为有些网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就不能通过邮件传送.这样用途就受到了很大的 ...

  3. c# java base64编码解码_C#教程之Base64编码解码原理及C#编程实例

    一. Base64编码由来 为什么会有Base64编码呢?因为有些网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就不能通过邮件传送.这样用途就受到了很大的 ...

  4. C# Base64编码/解码

    一.编码规则      Base64编码的思想是是采用64个基本的ASCII码字符对数据进行重新编码.它将需要编码的数据拆分成字节数组.以3个字节为一组.按顺序排列24 位数据,再把这24位数据分成4 ...

  5. 原来浏览器原生支持JS Base64编码解码

    原来浏览器原生支持JS Base64编码解码 转载来源:https://www.zhangxinxu.com/wordpress/2018/08/js-base64-atob-btoa-encode- ...

  6. Base64编解码原理并用Java手工实现Base64编解码

    Base64编解码原理 目前Base64已经成为网络上常见的传输8比特字节代码的编码方式之一.在做支付系统时,系统之间的报文交互都需要使用Base64对明文进行转码,然后进行签名或加密,之后再次Bas ...

  7. Base64编码/解码VB6超精简版(适用于中、英文)

    上次因为要编写自动登录邮箱的程序,需要Base64编码,但是我看了几种版本的VB下Base64编码的程序,发现要么就是太冗长,要么就是不支持中文,要么根本不能用,于是我想求人不如求己,便仔细研究了一下 ...

  8. js base64 编码解码

    js base64 编码解码 encode decode,可以直接使用 function Base64() {// private property_keyStr = "ABCDEFGHIJ ...

  9. python使用base64编码解码数据

    python使用base64编码解码数据 base64模块是用来作base64编码解码,常用于小型数据的传输.编码后的数据是一个字符串,其包括a-z.A-Z.0-9./.+共64个字符,即可用6个字节 ...

最新文章

  1. JSP针织生产管理系统
  2. Redis持久化机制 -全量同步与增量同步的区别
  3. OpenCV之feature2d 模块. 2D特征框架(2)特征描述 使用FLANN进行特征点匹配 使用二维特征点(Features2D)和单映射(Homography)寻找已知物体 平面物体检测
  4. 计算机考研:计算机组成原理考点分析
  5. 这是对R的误解!R的应用原来这么广!
  6. signature=8405d26e250ad07c44560263cb1d4fc0,Systems for analyzing microtissue arrays
  7. oracle rollup分组没有数据时为0_数据库周刊19│GBASE适配鲲鹏;MySQL窗口函数;OGG双向数据同步……...
  8. Microsoft 推出在AzureApp Service上支持Windows容器的公开预览版
  9. matlab图像基础处理小记
  10. java推送到 钉钉用户_javaweb利用钉钉机器人向钉钉群推送消息(解决中文乱码)...
  11. mysql数据库自学_MySQL数据库自学
  12. VBA自定义方法 快捷键设置
  13. 神舟计算机主板bios,神舟笔记本BIOS设置详解
  14. android投屏到web,安卓投屏神器下载|安卓投屏神器(Web Video Caster)v4.5.4高级版下载 - 99安卓游戏...
  15. 60分钟企业经营战略
  16. 音乐心理学 | 书籍推荐
  17. 美图android手机刷机教程,美图手机如何刷机
  18. 自然常数e的由来(简单通俗易于理解自然常数e)
  19. java特种兵读书笔记(3-5)——java程序员的OS之OOM
  20. 来一起造轮子:手写 Vue3 reactivity 模块

热门文章

  1. DEV GridView 部分属性
  2. ATamp;T汇编格式
  3. IntelliJ IDEA 下载安装及其破解
  4. nginx 反向代理和正向代理区别
  5. 【FPGA】Quartus Prime 20.1 精简版下载安装教程记录
  6. 开始→运行→命令 集锦
  7. 萨班斯法案:由来、影响及争论
  8. 'localtime': This function or variable may be unsafe. Consider using localtime_s instead.
  9. java远程连接linux并发送命令,两种方案比较Jsch与ganymed-ssh2
  10. 商家如何自己零成本免费制作点餐小程序