您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

为啥要做 base64 编码

时间:2021-05-14 13:25:03  来源:微信公众号  作者:程序员财富自由之路

在项目中,对豹纹进行压缩、加密后,最后一步一般是 base64 编码。因为 base64 编码的字符串更适合不同平台,不同语言的传输。

base64 编码的优点:

  • 算法是编码,不是压缩,编码后只会增加字节数(一般是比之前的多1/3,比如之前是3, 编码后是4)
  • 算法简单,基本不影响效率
  • 算法可逆,解码很方便,不用于私密传输。
  • 毕竟编码了,肉眼不能直接读出原始内容。
  • 加密后的字符串只有【0-9a-zA-Z+/=】 不可打印字符(转译字符)也可以传输

为啥要编码

计算机中任何数据都是 ASCII 码存储的, ascii 是 128-255 之间的不可见字符。在网络上进行数据交换,从 A 到 B, 往往要经过多个路由器,不同设备之间对字符的处理方式有一些不同,不可见字符有可能被错误处理,是不利于传输的,因此要先做一个 base64 编码,变成可见字符,这样出错的可能性比较大。

为啥要做 base64 编码

 

在这里插入图片描述

看看英文版怎么说:

When you have some binary data that you want to ship across a network, you generally don't do it by just streaming the bits and bytes over the wire in a raw format. Why? because some media are made for streaming text. You never know -- some protocols may interpret your binary data as control characters (like a modem), or your binary data could be screwed up because the underlying protocol might think that you've entered a special character combination (like how FTP translates line endings). So to get around this, people encode the binary data into characters. Base64 is one of these types of encodings. Why 64? Because you can generally rely on the same 64 characters being present in many character sets, and you can be reasonably confident that your data's going to end up on the other side of the wire uncorrupted.

使用场景

  • 对于证书来说,尤其是根证书,一般是 base64 编码的,在网上被很多人下载
  • 电子邮件的附件一般是 base64 编码,因为附件往往有不可见字符
  • 比如 http 协议中 key , value 字段的值,必须进行 URLEncode,因为有写特殊符号,有特殊含义,那么需要把这些字符传输完再解析回来。
  • xml 中如果像嵌入另外一个 xml 文件,直接嵌入,往往 xml 标签就乱套了, 不容易解析,因此,需要把 xml 编译成字节数组的字符串,编译成可见字符。
  • 网页中的一些小图片,可以直接以 base64 编码的方式嵌入,不用再链接请求消耗网络资源。
  • 较老的纯文本协议 SMTP ,这些文本偶尔传输一个文件时,需要用 base64

base64 编码步骤

  • 将待编码的字符串转换成二进制表示出来
  • 3个字节为一组,也就是24位二进制为一组
  • 将这个24位分成4组,每 6个为一组,每组签名补 00 将6为二进制转换成8个二进制,从原来的3字节转换为4字节
  • 计算这4个字节对应的十进制,然后跟 ASCII 表对应,拼接字符串形成最后的 base64 编码。

base64 源码

base64.h

#include "Base64.h"
 
const std::string CBase64::base64_chars =   
 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"  
 "abcdefghijklmnopqrstuvwxyz"  
 "0123456789+/";  
 
 
int CBase64::find_utf_8_bit_head(const unsigned char *src_content,int src_size )
{
 int i_ret = -1;
 int byteNum = 0;  //字符数
 if( src_content )
 { 
  for(int i = src_size-1; i >= 0; i--)
  {
   if( 0 == (src_content[i] >> 7 ) )
   {
    byteNum = 1;
    i_ret = src_size - i;
    break;
   }
   if( 0x06 == (src_content[i]>> 5) )
   {
    byteNum = 2;
    i_ret = src_size - i;
    break;
   }
   if( 0x0E == (src_content[i] >> 4) )
   {
    byteNum = 3;
    i_ret = src_size - i;
    break;
   }
   if( 0x1E == (src_content[i] >> 3) )
   {
    byteNum = 4;
    i_ret = src_size - i;
    break;
   }
   if( 0x3E == (src_content[i] >> 2) )
   {
    byteNum = 5;
    i_ret = src_size - i;
    break;
   }
   if( 0x7E == (src_content[i] >> 1) ) 
   {
    byteNum = 6;
    i_ret = src_size - i;
    break;
   }
  }
  if( i_ret == byteNum ) i_ret = -1;
 }
 return i_ret;
}
 
 
std::string CBase64::base64_encode(const unsigned char* bytes_to_encode, unsigned int in_len) {  
 std::string ret;  
 int i = 0;  
 int j = 0;  
 unsigned char char_array_3[3];  
 unsigned char char_array_4[4];  
 
 while (in_len--) {  
  char_array_3[i++] = *(bytes_to_encode++);  
  if (i == 3) {  
   char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;  
   char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);  
   char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);  
   char_array_4[3] = char_array_3[2] & 0x3f;  
 
   for(i = 0; (i <4) ; i++)  
    ret += base64_chars[char_array_4[i]];  
   i = 0;  
  }  
 }  
 
 if (i)  
 {  
  for(j = i; j < 3; j++)  
   char_array_3[j] = '';  
 
  char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;  
  char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);  
  char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);  
  char_array_4[3] = char_array_3[2] & 0x3f;  
 
  for (j = 0; (j < i + 1); j++)  
   ret += base64_chars[char_array_4[j]];  
 
  while((i++ < 3))  
   ret += '=';  
 
 }  
 
 return ret;  
 
}
 
 
//CString CBase64::Base64Encode(LPCTSTR lpszSrc)
//{
// char* strSrc = new char[_tcslen(lpszSrc)+1];
// ZeroMemory(strSrc, _tcslen(lpszSrc)+1);
// strcpy(strSrc, (char*)(_bstr_t(lpszSrc)));
// std::string str = base64_encode((unsigned char*)strSrc, (int)strlen(strSrc));
// CString strDst = str.c_str();
// return strDst;
//}
 
std::string CBase64::Base64Encode(char* lpszSrc)
{
 int str_len = strlen(lpszSrc);
 int find_index = find_utf_8_bit_head((unsigned char*)lpszSrc, str_len);
 if(find_index > -1)
 {
  memset(lpszSrc+(str_len-find_index), 0, find_index);
 }
 str_len = strlen(lpszSrc);
 return base64_encode((unsigned char*)lpszSrc, str_len);
}
 
std::string CBase64::base64_decode(const unsigned char* bytes_to_encode, unsigned int in_len) {  
 int i = 0;  
 int j = 0;  
 int in_ = 0;  
 unsigned char char_array_4[4], char_array_3[3];  
 std::string ret;  
 
 while (in_len-- && ( bytes_to_encode[in_] != '=') /*&& is_base64(bytes_to_encode[in_])*/) {  
  char_array_4[i++] = bytes_to_encode[in_]; in_++;  
  if (i ==4) {  
   for (i = 0; i <4; i++)  
    char_array_4[i] = base64_chars.find(char_array_4[i]);  
 
   char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);  
   char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);  
   char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];  
 
   for (i = 0; (i < 3); i++)  
    ret += char_array_3[i];  
   i = 0;  
  }  
 }  
 
 if (i) {  
  for (j = i; j <4; j++)  
   char_array_4[j] = 0;  
 
  for (j = 0; j <4; j++)  
   char_array_4[j] = base64_chars.find(char_array_4[j]);  
 
  char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);  
  char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);  
  char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];  
 
  for (j = 0; (j < i - 1); j++) ret += char_array_3[j];  
 }  
 
 return ret;  
}    
 
//CString CBase64::Base64Decode(LPCTSTR lpszSrc)
//{
// char* strSrc = new char[_tcslen(lpszSrc)+1];
// ZeroMemory(strSrc, _tcslen(lpszSrc)+1);
// strcpy(strSrc, (char*)(_bstr_t(lpszSrc)));
// std::string str = base64_decode((unsigned char*)strSrc, (int)strlen(strSrc));
// CString strDst = str.c_str();
// return strDst;
//}
 
std::string CBase64::Base64Decode(char* lpszSrc)
{
 return base64_decode((unsigned char*)lpszSrc, (int)strlen(lpszSrc));
}

base64.cpp

#include "Base64.h"
 
const std::string CBase64::base64_chars =   
 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"  
 "abcdefghijklmnopqrstuvwxyz"  
 "0123456789+/";  
 
 
int CBase64::find_utf_8_bit_head(const unsigned char *src_content,int src_size )
{
 int i_ret = -1;
 int byteNum = 0;  //字符数
 if( src_content )
 { 
  for(int i = src_size-1; i >= 0; i--)
  {
   if( 0 == (src_content[i] >> 7 ) )
   {
    byteNum = 1;
    i_ret = src_size - i;
    break;
   }
   if( 0x06 == (src_content[i]>> 5) )
   {
    byteNum = 2;
    i_ret = src_size - i;
    break;
   }
   if( 0x0E == (src_content[i] >> 4) )
   {
    byteNum = 3;
    i_ret = src_size - i;
    break;
   }
   if( 0x1E == (src_content[i] >> 3) )
   {
    byteNum = 4;
    i_ret = src_size - i;
    break;
   }
   if( 0x3E == (src_content[i] >> 2) )
   {
    byteNum = 5;
    i_ret = src_size - i;
    break;
   }
   if( 0x7E == (src_content[i] >> 1) ) 
   {
    byteNum = 6;
    i_ret = src_size - i;
    break;
   }
  }
  if( i_ret == byteNum ) i_ret = -1;
 }
 return i_ret;
}
 
 
std::string CBase64::base64_encode(const unsigned char* bytes_to_encode, unsigned int in_len) {  
 std::string ret;  
 int i = 0;  
 int j = 0;  
 unsigned char char_array_3[3];  
 unsigned char char_array_4[4];  
 
 while (in_len--) {  
  char_array_3[i++] = *(bytes_to_encode++);  
  if (i == 3) {  
   char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;  
   char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);  
   char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);  
   char_array_4[3] = char_array_3[2] & 0x3f;  
 
   for(i = 0; (i <4) ; i++)  
    ret += base64_chars[char_array_4[i]];  
   i = 0;  
  }  
 }  
 
 if (i)  
 {  
  for(j = i; j < 3; j++)  
   char_array_3[j] = '';  
 
  char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;  
  char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);  
  char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);  
  char_array_4[3] = char_array_3[2] & 0x3f;  
 
  for (j = 0; (j < i + 1); j++)  
   ret += base64_chars[char_array_4[j]];  
 
  while((i++ < 3))  
   ret += '=';  
 
 }  
 
 return ret;  
 
}
 
 
//CString CBase64::Base64Encode(LPCTSTR lpszSrc)
//{
// char* strSrc = new char[_tcslen(lpszSrc)+1];
// ZeroMemory(strSrc, _tcslen(lpszSrc)+1);
// strcpy(strSrc, (char*)(_bstr_t(lpszSrc)));
// std::string str = base64_encode((unsigned char*)strSrc, (int)strlen(strSrc));
// CString strDst = str.c_str();
// return strDst;
//}
 
std::string CBase64::Base64Encode(char* lpszSrc)
{
 int str_len = strlen(lpszSrc);
 int find_index = find_utf_8_bit_head((unsigned char*)lpszSrc, str_len);
 if(find_index > -1)
 {
  memset(lpszSrc+(str_len-find_index), 0, find_index);
 }
 str_len = strlen(lpszSrc);
 return base64_encode((unsigned char*)lpszSrc, str_len);
}
 
std::string CBase64::base64_decode(const unsigned char* bytes_to_encode, unsigned int in_len) {  
 int i = 0;  
 int j = 0;  
 int in_ = 0;  
 unsigned char char_array_4[4], char_array_3[3];  
 std::string ret;  
 
 while (in_len-- && ( bytes_to_encode[in_] != '=') /*&& is_base64(bytes_to_encode[in_])*/) {  
  char_array_4[i++] = bytes_to_encode[in_]; in_++;  
  if (i ==4) {  
   for (i = 0; i <4; i++)  
    char_array_4[i] = base64_chars.find(char_array_4[i]);  
 
   char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);  
   char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);  
   char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];  
 
   for (i = 0; (i < 3); i++)  
    ret += char_array_3[i];  
   i = 0;  
  }  
 }  
 
 if (i) {  
  for (j = i; j <4; j++)  
   char_array_4[j] = 0;  
 
  for (j = 0; j <4; j++)  
   char_array_4[j] = base64_chars.find(char_array_4[j]);  
 
  char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);  
  char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);  
  char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];  
 
  for (j = 0; (j < i - 1); j++) ret += char_array_3[j];  
 }  
 
 return ret;  
}    
 
//CString CBase64::Base64Decode(LPCTSTR lpszSrc)
//{
// char* strSrc = new char[_tcslen(lpszSrc)+1];
// ZeroMemory(strSrc, _tcslen(lpszSrc)+1);
// strcpy(strSrc, (char*)(_bstr_t(lpszSrc)));
// std::string str = base64_decode((unsigned char*)strSrc, (int)strlen(strSrc));
// CString strDst = str.c_str();
// return strDst;
//}
 
std::string CBase64::Base64Decode(char* lpszSrc)
{
 return base64_decode((unsigned char*)lpszSrc, (int)strlen(lpszSrc));
}

欢迎关注公众号:程序员开发者社区

参考资料

  • https://opensource.sensorsdata.cn/question-daily/2020-03-31/


Tags:base64   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
在项目中,对豹纹进行压缩、加密后,最后一步一般是 base64 编码。因为 base64 编码的字符串更适合不同平台,不同语言的传输。base64 编码的优点: 算法是编码,不是压缩,编码后只会增...【详细内容】
2021-05-14  Tags: base64  点击:(211)  评论:(0)  加入收藏
java 中怎样实现Base64的编码 结果为:V29ybGQ=Base64 是怎么编码的?ASCII 码表第一步: World 中的每个字母根据上面的ASCII码,转换成二进制 第二步:把 第一步生成的二进制 重新...【详细内容】
2020-02-22  Tags: base64  点击:(118)  评论:(0)  加入收藏
Base64编码解码算是网络安全领域的很小而且很简单的一个知识点了,虽然简单但是应用场景却极其广泛,可以这样说,开发者要是不懂Base64,基本上可以告别程序员生涯了。这篇文章从原...【详细内容】
2019-10-11  Tags: base64  点击:(146)  评论:(0)  加入收藏
1.js中对字符串进行base64编码和解码function Base64() { // private property _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; // publ...【详细内容】
2019-10-11  Tags: base64  点击:(237)  评论:(0)  加入收藏
Base64编码解码算是网络安全领域的很小而且很简单的一个知识点了,虽然简单但是应用场景却极其广泛,可以这样说,开发者要是不懂Base64,基本上可以告别程序员生涯了。这篇文章从原...【详细内容】
2019-09-19  Tags: base64  点击:(181)  评论:(0)  加入收藏
在做接口的时候,我们需要对数据进行加密处理,本例使用的是AES/DES加密解密方法,因为在加密解密的过程中,加密的串是乱码的,所以加乱码的串进行了base64编码或者转为16进制同理解...【详细内容】
2019-08-07  Tags: base64  点击:(316)  评论:(0)  加入收藏
本文原创作者:源理君头条号:底层软件架构公众号:技术原理君开始在互联网中的每一刻,你可能都在享受着Base64带来的便捷,但对于Base64的基础原理又了解多少?今天这篇文章带领大家了...【详细内容】
2019-06-28  Tags: base64  点击:(525)  评论:(0)  加入收藏
▌简易百科推荐
摘 要 (OF作品展示)OF之前介绍了用python实现数据可视化、数据分析及一些小项目,但基本都是后端的知识。想要做一个好看的可视化大屏,我们还要学一些前端的知识(vue),网上有很多比...【详细内容】
2021-12-27  项目与数据管理    Tags:Vue   点击:(1)  评论:(0)  加入收藏
程序是如何被执行的&emsp;&emsp;程序是如何被执行的?许多开发者可能也没法回答这个问题,大多数人更注重的是如何编写程序,却不会太注意编写好的程序是如何被运行,这并不是一个好...【详细内容】
2021-12-23  IT学习日记    Tags:程序   点击:(9)  评论:(0)  加入收藏
阅读收获✔️1. 了解单点登录实现原理✔️2. 掌握快速使用xxl-sso接入单点登录功能一、早期的多系统登录解决方案 单系统登录解决方案的核心是cookie,cookie携带会话id在浏览器...【详细内容】
2021-12-23  程序yuan    Tags:单点登录(   点击:(8)  评论:(0)  加入收藏
下载Eclipse RCP IDE如果你电脑上还没有安装Eclipse,那么请到这里下载对应版本的软件进行安装。具体的安装步骤就不在这赘述了。创建第一个标准Eclipse RCP应用(总共分为六步)1...【详细内容】
2021-12-22  阿福ChrisYuan    Tags:RCP应用   点击:(7)  评论:(0)  加入收藏
今天想简单聊一聊 Token 的 Value Capture,就是币的价值问题。首先说明啊,这个话题包含的内容非常之光,Token 的经济学设计也可以包含诸多问题,所以几乎不可能把这个问题说的清...【详细内容】
2021-12-21  唐少华TSH    Tags:Token   点击:(9)  评论:(0)  加入收藏
实现效果:假如有10条数据,分组展示,默认在当前页面展示4个,点击换一批,从第5个开始继续展示,到最后一组,再重新返回到第一组 data() { return { qList: [], //处理后...【详细内容】
2021-12-17  Mason程    Tags:VUE   点击:(14)  评论:(0)  加入收藏
什么是性能调优?(what) 为什么需要性能调优?(why) 什么时候需要性能调优?(when) 什么地方需要性能调优?(where) 什么时候来进行性能调优?(who) 怎么样进行性能调优?(How) 硬件配...【详细内容】
2021-12-16  软件测试小p    Tags:性能调优   点击:(19)  评论:(0)  加入收藏
Tasker 是一款适用于 Android 设备的高级自动化应用,它可以通过脚本让重复性的操作自动运行,提高效率。 不知道从哪里听说的抖音 app 会导致 OLED 屏幕烧屏。于是就现学现卖,自...【详细内容】
2021-12-15  ITBang    Tags:抖音防烧屏   点击:(23)  评论:(0)  加入收藏
11 月 23 日,Rust Moderation Team(审核团队)在 GitHub 上发布了辞职公告,即刻生效。根据公告,审核团队集体辞职是为了抗议 Rust 核心团队(Core team)在执行社区行为准则和标准上...【详细内容】
2021-12-15  InfoQ    Tags:Rust   点击:(24)  评论:(0)  加入收藏
一个项目的大部分API,测试用例在参数和参数值等信息会有很多相似的地方。我们可以复制API,复制用例来快速生成,然后做细微调整既可以满足我们的测试需求1.复制API:在菜单发布单...【详细内容】
2021-12-14  AutoMeter    Tags:AutoMeter   点击:(20)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条