Base64是一种很常见的编码规范,其定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.),其作用是将二进制序列转换为人类可读的ASCII字符序列,常用在需用通过文本来传输二进制数据的协议中,如HTTP和SMTP等。

Base64编码规则:对于待编码数据,以3个字节为单位,依次取6位,前两位补0形成8位编码,由于3*8=4*6,3个字节的输入会编码成4个字节的输出。如果剩下的字符不足3个字节,则用0填充,输出字符使用'=',因此编码后输出的文本末尾可能会出现1或2个'='。

为了保证所输出的编码位可读字符,Base64制定了一个编码表,以便进行统一转换。编码表的大小为2^6=64,这也是Base64名称的由来。

Base64编码表

码值   码   码值  码  码值码  码值  码
      0         A       17       R       34     i       51     z
      1         B       18       S       35     j       52     0
      2         C       19       T       36     k      53     1
      3         D       20       U       37     l       54     2
      4         E       21        V       38     m     55    3
      5         F        22       W      39     n      56    4
      6         G        23       X       40     o      57     5
      7         H        24       Y       41     p      58     6
      8         I          25       Z       42     q      59     7
      9         J         26       a       43      r      60     8
      0         K         27       b       44     s      61    9
      11       L         28       c       45      t       62    +
      12       M         29      d       46      u      63    /
      13       N         30      e       47      v
      14       O         31       f        48     w      (pad) =
      15       P         32       g       49 x
      16       Q         33       h       50 y

编码详解

1. 不加后补位的字符串“abC”

01100001 01100010 01000011
00011000 00010110 00001001 00000011

24       22       9        3

查表可以得到编码值为:“YWJD”。

2. 加后补位的字符串“ab”:

01100001 01100010
00011000 00010110 00001000 00000000

24       22       8        -

由于不够24个字节位,所以我们要加8个0字节位以凑够24个。“-”表示增加的补位,编码后应为“=”,所以可以得到编码后的字符串为“YWI=”。

3. 加后补位的字符串“a”:

01100001

00011000 00010000 00000000 00000000

24       16       -        -

同样,编码后的字符串为“YQ==”,只是这里出现了两个“=”。

算法实现:

// Decode a block (4 bytes)

void decodeBlock(unsigned char *dest, char *src)
{
  unsigned int x = 0;
  int i;
  for(i = 0; i < 4; i++) {
    if(src[i] >= 'A' && src[i] <= 'Z')
      x = (x << 6) + (unsigned int)(src[i] - 'A' + 0);
    else if(src[i] >= 'a' && src[i] <= 'z')
      x = (x << 6) + (unsigned int)(src[i] - 'a' + 26);
    else if(src[i] >= '0' && src[i] <= '9')
      x = (x << 6) + (unsigned int)(src[i] - '0' + 52);
    else if(src[i] == '+')
      x = (x << 6) + 62;
    else if(src[i] == '/')
      x = (x << 6) + 63;
    else if(src[i] == '=')
      x = (x << 6);
  }

dest[2] = (unsigned char)(x & 255); x >>= 8;
  dest[1] = (unsigned char)(x & 255); x >>= 8;
  dest[0] = (unsigned char)(x & 255); x >>= 8;
}

// decode the src string and store the decoded string to dest, return the

// length of decoded string in len

// NOTE: the length of dest buffer must be larger than (strlen(src)*3)/4+3
void base64Decode(unsigned char *dest, char *src, int *len)
{
  int length = 0;
  int equalsTerm = 0;
  int i;
  int numBlocks;
  unsigned char lastBlock[3];

while((src[length] != '=') && src[length])
    length++;
  while(src[length+equalsTerm] == '=')
    equalsTerm++;

numBlocks = (length + equalsTerm) / 4;
  if(len)
    *len = (numBlocks * 3) - equalsTerm;

for(i = 0; i < numBlocks - 1; i++) {
    decodeBlock(dest, src);
    dest += 3;

src += 4;
  }

decodeBlock(lastBlock, src);
  for(i = 0; i < 3 - equalsTerm; i++)
    dest[i] = lastBlock[i];

}

static char table64[]=
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

// encode the data from inbuf and store the encoded data into outbuf

// return the length of encoded data

// NOTE: do not forget to free the outbuf allocated here
int base64Encode(const void *inbuf, int inlen, char **outbuf)
{
  unsigned char ibuf[3];
  unsigned char obuf[4];
  int i;
  int inputparts;
  char *output;
  char *base64data;

char *indata = (char *)inbuf;

if(0 == inlen)
    inlen = strlen(indata);

base64data = output = (char*)malloc(inlen*4/3+4);
  if(NULL == output)
    return -1;

while(inlen > 0) {
    for (i = inputparts = 0; i < 3; i++) {
      if(inlen > 0) {
        inputparts++;
        ibuf[i] = *indata;
        indata++;
        inlen--;
      }
      else
        ibuf[i] = 0;
    }

obuf [0] = (ibuf [0] & 0xFC) >> 2;
    obuf [1] = ((ibuf [0] & 0x03) << 4) | ((ibuf [1] & 0xF0) >> 4);
    obuf [2] = ((ibuf [1] & 0x0F) << 2) | ((ibuf [2] & 0xC0) >> 6);
    obuf [3] = ibuf [2] & 0x3F;

switch(inputparts) {
    case 1: /* only one byte read, two '=' needed */
      sprintf(output, "%c%c==",
              table64[obuf[0]],
              table64[obuf[1]]);
      break;
    case 2: /* two bytes read, one '=' needed */
      sprintf(output, "%c%c%c=",
              table64[obuf[0]],
              table64[obuf[1]],
              table64[obuf[2]]);
      break;
    default:
      sprintf(output, "%c%c%c%c",
              table64[obuf[0]],
              table64[obuf[1]],
              table64[obuf[2]],
              table64[obuf[3]] );
      break;
    }
    output += 4;
  }
  *output=0;
  *outbuf = base64data;

return strlen(base64data);
}

-----------------------------

部分资料来自互联网,转载请注明作者及出处,谢谢!

转载于:https://blog.51cto.com/freshpassport/619286

Base64编码解码与实现相关推荐

  1. js base64 编码解码

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

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

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

  3. java svgbase64转byte_java 图片进行base64 编码解码

    java 图片进行base64 编码解码 刘振兴 代码分享 2017年06月07日 10555 2条评论 import sun.misc.BASE64Decoder; import sun.misc. ...

  4. openssl算法 —— 利用openssl进行BASE64编码解码、md5/sha1摘要、AES/DES3加密解密

    openssl 加密字符串的方法: 一.利用openssl命令进行BASE64编码解码(base64 encode/decode): 1. BASE64编码命令 对字符串'abc'进行base64编码 ...

  5. Java工程中引用Base64编码解码小记

    Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一. Base64编码说明 Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两 ...

  6. Java Base64 编码解码方案总结

    转载自  Java Base64 编码解码方案总结 Base64是一种能将任意Binary资料用64种字元组合成字串的方法,而这个Binary资料和字串资料彼此之间是可以互相转换的,十分方便.在实际应 ...

  7. 一些Base64编码/解码及数据压缩/解压方面的知识

    一.Base64编码/解码 一般用到的是Delphi自带的单元EncdDecd,当然还有第三方提供的单元或控件,其中我所接触到的认为比较好的有Indy的TIdMimeEncode / TIdMimeD ...

  8. Javascript中Base64编码解码的使用实例

    Javascript为我们提供了一个简单的方法来实现字符串的Base64编码和解码,分别是window.btoa()函数和window.atob()函数. 1 var encodedStr = win ...

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

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

  10. python实现base64解码_Python实现base64编码解码

    Python实现base64编码解码 通过编程了解base64编码解码过程 (纯属无聊之举,且不支持汉字) a = input("输入(1.base64加密/2.base64解密):&quo ...

最新文章

  1. 全国大学生智能汽车竞赛 --智慧物流创意组
  2. 虚幻引擎UE4-命令行使用的一些技巧
  3. ADO.NET教程(一)
  4. IntelliJ IDEA---java的编译工具【转】
  5. 工具之wireshark保存rtp数据
  6. JAVAFX-1 开发应用
  7. CVS update常用技巧
  8. QT制作自定义进度条(圆环状)
  9. tcp/ip协议详解
  10. 全国计算机等级考试二级教程--C语言程序设计(2018年版) 随手笔记(一)
  11. 基于python3,抓取韩寒博客文章
  12. Pr全套视频教程 PR 全套零基础从入门到精通视频教程
  13. java poi设置导出的excel带下拉
  14. mysql 数据库大小写敏感(数据库的名字、表名字、字段名字、字段值)
  15. 华为天才少年稚晖君做了一把模块化机械键盘,引起极客圈地震,网友:这才是真正的客制化...
  16. python饼图 立体_【Python基础】惊叹,Pyecharts绘制饼图原来可以如此漂亮!
  17. Google Play支付:测试报错“无法购买您要的商品”问题
  18. 7-1 厘米换算英尺英寸 (15 分)Java
  19. 入职一个月老大教我如何在做测试中运用Linux
  20. 【GlobalMapper精品教程】006:Excel等表格(.xls)或文本(.txt .csv)坐标文件生成矢量点

热门文章

  1. 从零搭建 vue-cli 脚手架
  2. STL_算法_区间的比較(equal、mismatch、 lexicographical_compare)
  3. 【网络基础】路由表,分组转发算法
  4. Flume1.5.0的安装、部署、简单应用(含伪分布式、与hadoop2.2.0、hbase0.96的案例)
  5. 监控自定义信息 —— ESFramework 4.0 快速上手(10)
  6. 数据科学最常用流程CRISP-DM,终于有人讲明白了
  7. 10本书,搞定这门全球1000万程序员在用的编程语言
  8. FreeModbus输入寄存器
  9. 求解九宫格的Java_使用全排列方法解九宫格问题
  10. 7000 字,四年多 Java 的 BAT 面经分享!