浅谈Base64编码(转)

Java 实现 Base64 加密&解密方法 Base64 编码是程序开发中比较常用的一种编码算法,是常用来存储或传输一些二进制数据的方法,也是 MIME(多用途互联网邮件扩展)中的一种编码方法 。Base64 可以实现将任何数据转换为可打印字符表示的字符串,避免数据在传输过程中失真,Base64 最开始用来在邮件发送中将非 ASCLL 字符内容转换为 ASCLL字符。标准 Base64 是一种用于传输 8Bit 字节码的编码方式之一,基于 64 个可打印字符来表示二进制数据,使用的可打印字符包括有:A-Z、a-z、0-9、+、/ 共 64 个。Url 阅读详情

我打赌当你见到Base64这个词的时候你会觉得在哪里见过,因为在你能够上网看到这篇文章的时候你已经在后台使用它了。如果您对二进制数有所了解,你就可以开始读它了。

打开一封Email,查看其原始信息(您可以通过收取、导出该邮件用文本编辑器查看)。你会看到类似这样的一个效果:

Date: Thu, 25 Dec 2003 06:33:07 +0800
From: "eSX?!" <snaix@yeah.net'>snaix@yeah.net'>snaix@yeah.net'>snaix@yeah.net>
Reply-To: snaix@yeah.net'>snaix@yeah.net'>snaix@yeah.net'>snaix@yeah.net
To: "snaix" <snaix@126.com'>snaix@126.com>
Subject:
X-mailer: Foxmail 5.0 beta2 [cn]
Mime-Version: 1.0
Content-Type: text/plain;
charset="gb2312"
Content-Transfer-Encoding: base64

xOO6w6OsU25haVgNCg0KoaGhodXiysfSu7j2QmFzZTY0tcSy4srU08q8/qOhDQoNCkJlc3QgV2lz
aGVzIQ0KIAkJCQkNCqGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaEgICAgICAgICAgICAgICBl
U1g/IQ0KoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoSAgICAgICAgICAgICAgIHNuYWl4QHll
YWgubmV0DQqhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhICAgICAgICAgMjAwMy0x
Mi0yNQ0K

是否看到了“base64”标记?是否看到了标记下面的一行乱码?也许你会恍然大悟,对!这就是Base64编码。

什么是Base64?

按照RFC2045的定义,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.)

为什么要使用Base64?

在设计这个编码的时候,我想设计人员最主要考虑了3个问题:
1.是否加密?
2.加密算法复杂程度和效率
3.如何处理传输?

    加密是肯定的,但是加密的目的不是让用户发送非常安全的Email。这种加密方式主要就是“防君子不防小人”。即达到一眼望去完全看不出内容即可。
基于这个目的加密算法的复杂程度和效率也就不能太大和太低。和上一个理由类似,MIME协议等用于发送Email的协议解决的是如何收发Email,而并不是如何安全的收发Email。因此算法的复杂程度要小,效率要高,否则因为发送Email而大量占用资源,路就有点走歪了。

    但是,如果是基于以上两点,那么我们使用最简单的恺撒法即可,为什么Base64看起来要比恺撒法复杂呢?这是因为在Email的传送过程中,由于历史原因,Email只被允许传送ASCII字符,即一个8位字节的低7位。因此,如果您发送了一封带有非ASCII字符(即字节的最高位是1)的Email通过有“历史问题”的网关时就可能会出现问题。网关可能会把最高位置为0!很明显,问题就这样产生了!因此,为了能够正常的传送Email,这个问题就必须考虑!所以,单单靠改变字母的位置的恺撒之类的方案也就不行了。关于这一点可以参考RFC2046。
基于以上的一些主要原因产生了Base64编码。

算法详解

    Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。
具体转化形式间下图:
字符串“张3”
11010101 11000101 00110011

00110101 00011100 00010100 00110011
表1

可以这么考虑:把8位的字节连成一串110101011100010100110011
然后每次顺序选6个出来之后再把这6二进制数前面再添加两个0,就成了一个新的字节。之后再选出6个来,再添加0,依此类推,直到24个二进制数全部被选完。
让我们来看看实际结果:

字符串“张3”
11010101 HEX:D5 11000101 HEX:C5 00110011 HEX:33

00110101 00011100 00010100 00110011
字符’5’ 字符’^/’ 字符’^T’ 字符’3’
十进制53 十进制34 十进制20 十进制51
表2

这样“张3 ”这个字符串就被Base64表示为”5^/^T3”了么?。错!
Base64编码方式并不是单纯利用转化完的内容进行编码。像’^/’字符是控制字符,并不能通过计算机显示出来,在某些场合就不能使用了。Base64有其自身的编码表:

Table 1: The Base64 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
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
10 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 (pad) =
14 O 31 f 48 w
15 P 32 g 49 x
16 Q 33 h 50 y
表3

这也是Base64名称的由来,而Base64编码的结果不是根据算法把编码变为高两位是0而低6为代表数据,而是变为了上表的形式,如”A”就有7位,而”a”就只有6位。表中,编码的编号对应的是得出的新字节的十进制值。因此,从表2可以得到对应的Base64编码:

字符串“张3”
11010101 HEX:D5 11000101 HEX:C5 00110011 HEX:33

00110101 00011100 00010100 00110011
字符’5’ 字符’^/’ 字符’^T’ 字符’3’
十进制53 十进制28 十进制20 十进制51
字符’1’ 字符’c’ 字符’U’ 字符’z’
表4

这样,字符串“张3”经过编码后就成了字符串“1cUz”了。
Base64将3个字节转变为4个字节,因此,编码后的代码量(以字节为单位,下同)约比编码前的代码量多了1/3。之所以说是“约”,是因为如果代码量正好是3的整数倍,那么自然是多了1/3。但如果不是呢?
细心的人可能已经注意到了,在The Base64 Alphabet中的最后一个有一个(pad) =字符。这个字符的目的就是用来处理这个问题的。
当代码量不是3的整数倍时,代码量/3的余数自然就是2或者1。转换的时候,结果不够6位的用0来补上相应的位置,之后再在6位的前面补两个0。转换完空出的结果就用就用“=”来补位。譬如结果若最后余下的为2个字节的“张”:

字符串“张”
11010101 HEX:D5 11000101 HEX:C5

00110101 00011100 00010100
十进制53 十进制28 十进制20 pad
字符’1’ 字符’c’ 字符’U’ 字符’=’
表6

这样,最后的2个字节被整理成了“1cU=”。
同理,若原代码只剩下一个字节,那么将会添加两个“=”。只有这两种情况,所以,Base64的编码最多会在编码结尾有两个“=”
至于将Base64的解码,只是一个简单的编码的逆过程,读者可以自己探讨。我将在文章的最后给出解码算法。

算法实现
其实在算法详解的时候基本上已经说的很清楚了。用于程序上,除去约束判断,大概可以分为如下几步几步:
读取数据3字节用AND取前6位,放入新的变量中右移两位,高两位清0AND取第一个字节的后2位和第二个字节的前4位移位放入新变量中右移两位,清0……依此类推。
解码的类C语言实现的算法:
BYTE LMoveBit(int base, int MoveNum)
{
BYTE result=base;
if(MoveNum==0)return 1;
if(MoveNum==1)return MoveNum;
result=base<<(MoveNum-1);
return result;
}

char base64_alphabet[]=
{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/','='};
BYTE Base64Decode(char *base64code, DWORD base64length)
{
char buf[4];
int i,j;
int k;
int l=0;
BYTE temp1[4],temp2;
BYTE *Buffer=new BYTE[base64length*3/4];
DWORD base64a=(base64length/4)-1;
DWORD base64b=0;
for(;base64b<base64a+1;base64b++)
{
for(i=0;i<4;i++)
{
buf[i]=*(base64code+(base64b*4)+i);
for(j=0;j<65;j++)
{
if(buf[i]==base64_alphabet[j])
{
temp1[i]=j;
break;
}
}
}
i--;
for(k=1;k<4;k++)
{
if(temp1[i-(k-1)]==64){m_padnum++; continue;}
temp1[i-(k-1)]=temp1[i-(k-1)]/LMoveBit(2,(k-1)*2);
temp2=temp1[i-k];
temp2=temp2&(LMoveBit(2,k*2)-1);
temp2*=LMoveBit(2,8-(2*k));//move 4
temp1[i-(k-1)]=temp1[i-(k-1)]+temp2;
Buffer[base64b*3+(3-k)]=temp1[i-(k-1)];
}
}
return Buffer;
}

根据这段算法,文章最开始给出的Email内容,可以解码为:
你好,SnaiX

  这是一个Base64的测试邮件!

Best Wishes!
               eSX?!
               snaix@yeah.net'>snaix@yeah.net'>snaix@yeah.net'>snaix@yeah.net
                  2003-12-25

常见的加密算法原理与实现:base64编码(加密) 系列一:base64加密前沿一、base64的缘起二、base64的原理三、在Python中的实现二级目录三级目录 前沿 一、base64的缘起 二、base64的原理 三、在Python中的实现 二级目录 三级目录 阅读详情

相关推荐

常见加密算法总结-base系列部分

文章目录常见加密算法总结-base系列部分附上链接自己的总结base系列编码base64介绍字典加密原理图加密代码解密索引表解密代码base32介绍字典一字典二加密原理图解密base16介绍编码表加密原理图代码base58编码 常见加密算法总结-base系列部分 附上链接 参考学长的:https://the_itach1.gitee.io/2021/01/18/%E4%B8%80%E4%BA%9B%E5%B8%B8%E7%94%A8%E7%AE%97%E6%B3%95/ 自己的总结 base系列编码 ba

m0_62690279的博客 3568

如何对数据进行Base64编码(转载)

                            浅谈Base64编码来源:CSTC 作者:朱岩 我打赌当你见到Base64这个词的时候你会觉得在哪里见过,因为在你能够上网看到这篇文章的时候你已经在后台使用它了。如果您对二进制数有所了解,你就可以开始读它了。打开一封Email,查看其原始信息(您可以通过收取、导出该邮件用文本编辑器查看)。你会看到类似这样的一个效果: Date: Thu, 2

64M便当的专栏 1848

【PT+Arduino+OneNET基础教程1】PacketTracer中MCU芯片编程教程(零基础入门)

PacketTracer软件内MCU芯片编程入门 零基础

ChloeMax_的博客 9451

base64加密及方式

base64编码 出于数据加密的目的或者网络协议的限制或者特殊字符的处理等,通常需要将原文转换为base64编码,比如:发送某些含有 ASCII 码表中 0 到 31 之间的控制字符的数据。 常见转换方式 1.使用window.btoa() 编码,使用window.atob() 解码 案例: 注意:此方式只支持ASCII 编码 ,如果编码中有中文或者sql中的特殊字符等则会报错:The string to be encoded contains characters outside of the L

qq_43050077的博客 1万+

保姆级教程:用Protege 5.5.0从零构建你的第一个知识图谱(附实战案例文件)

本文提供了一份详细的Protege 5.5.0使用指南,从零开始构建知识图谱。涵盖环境配置、本体结构设计、实例填充到可视化展示的全流程,特别适合初学者快速掌握知识建模技术。通过实战案例演示,帮助读者理解如何定义类、属性及建立实例关系,是学习知识图谱构建的实用教程。

weixin_42548816的博客 553

单片机控制双向可控硅的5种实用触发电路设计(附完整电路图)

本文深入解析了单片机控制双向可控硅的5种实用触发电路设计,涵盖从基础隔离到复杂负载驱动的实战方案。重点探讨了光电耦合器选型、过零检测同步、RC吸收电路精密计算以及应对感性负载和高噪声环境的加固策略,并提供了完整的电路图与调试避坑指南,旨在帮助开发者实现安全可靠的交流负载控制。

joy55的博客 2194

【转】浅谈Base64编码

<br />什么是Base64?<br /><br />按照RFC2045的定义,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.) <br /><br />为什么要使用Bas

tenfyguo的技术专栏 538

Langfuse落地教程:从Docker部署到项目接入,掌控LLM调用链路

大模型应用开发中,调用链路的透明度直接决定调试效率与成本控制。可观测性技术通过记录每次请求的输入、输出、模型参数与Token消耗,帮助开发者快速定位问题。Langfuse作为开源LLM可观测性平台,将Trace、Prompt版本管理、评分等能力集成于一体,支持Docker Compose自托管部署,并提供Python/JS SDK与REST API。借助部署后的控制台,团队能够直观追踪RAG检索、Agent工具调用等复杂流程中的每一步耗时与资源占用,实现从黑盒调用到全链路可视化的转变。无论是本地调试、线上排

weixin_29698641的博客 308

浅谈Base64编码[转]

问题来源 使用方法Convert.ToBase64String时候不知所以然。 所以在网上查了点资料: 浅谈Base64编码 我打赌当你见到Base64这个词的时候你会觉得在哪里见过,因为在你能够上网看到这篇文章的时候你已经在后台使用它了。如果您对二进制数有所了解,你就可以开始读它了。 打开一封Email,查看其原始信息(您可以通过收取、导出该邮件用文本编辑器查看)。你会看到类似这样的...

weixin_30216561的博客 125

RAGFlow 离线部署:解决cl100k_base.tiktoken问题

摘要 本文详细解决了RAGFlow离线部署时tiktoken缓存文件下载失败的问题。通过分析tiktoken库的缓存机制,一次性不改代码解决.

baidu_25691461的博客 830

AI Agent的知识蒸馏链:多阶段LLM模型优化

随着大语言模型(LLM)规模的不断扩大,如何在保持模型性能的同时提高其部署效率成为关键挑战。本文旨在探讨通过知识蒸馏技术构建多阶段优化链,实现LLM模型的高效压缩和性能优化。研究范围涵盖从基础理论到实际应用的完整知识蒸馏流程,特别关注AI Agent场景下的特殊需求和解决方案。本文首先介绍知识蒸馏的基本概念和背景,然后详细阐述多阶段蒸馏链的核心原理。接着,我们将深入探讨算法实现细节和数学模型,提供完整的代码示例。最后讨论实际应用、工具资源和未来发展方向。

AI大模型应用之禅 350

(转)浅谈Base64编码

我打赌当你见到Base64这个词的时候你会觉得在哪里见过,因为在你能够上网看到这篇文章的时候你已经在后台使用它了。如果您对二进制数有所了解,你就可以开始读它了。 打开一封Email,查看其原始信息(您可以通过收取、导出该邮件用文本编辑器查看)。你会看到类似这样的一个效果: Date: Thu, 25 Dec 2003 06:33:07 +0800...

weixin_33810006的博客 95

FC7300 SPI MCAL配置引导

Example - QMI8A01z外设:Example - QMI8A01z外设:

舊梦的博客 257

浅谈base64编码

Base64 是一种用于将二进制数据编码为文本的方法,通常用于在网络传输中传递数据或存储数据。Base64 编码会将原始数据转换为由大小写字母、数字和特殊字符组成的 ASCII 字符串。这种编码方式可以确保数据在传输过程中不会被意外修改,同时也能解决某些数据格式无法直接表示文本的问题。Base64 编码后的字符串长度通常会比原始二进制数据略长。

Bruce_xiaowei的博客 2627

Allegro DXF板框导入及将元器件精准放置到特定位置操作

DXF板框导入 选择File-> import -> DXF 点开DXF file 查找文件 3. 选择需要导入的DXF文件 4. 通常结构文件使用的是米制单位,将单位选择为mm,如果不确定DXF 图纸坐标大小,建议勾选incremental addition,软件根据实际DXF图纸大小自动调整背景坐标尺寸以适应DXF图纸 5.打开Edit/View layers 6. 勾选 select all,选择DXF文件所有层;class 一栏选择BOARD GEOMETRY;subcla

sinat_15677011的博客 1万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

浅谈 Base64 编码与解码:原理、变体及实践

Base64是一种将二进制数据编码为文本的常用方案,其核心是将输入字节流按6位一组映射到64个可打印字符。标准Base64使用字符A-Z、a-z、0-9、+和/,而Base64url变体则将+和/替换为-和_以适配URL等场景。编码过程遵循3字节转4字符的规则,体积膨胀约33%。解码时需反向操作,通过位运算恢复原始数据。Base64不提供加密,仅解决二进制数据在文本协议中的兼容性问题。工程实践中需注意字符集转换、填充处理以及变体间的互转规则,避免常见误区。

青衫客36的博客 1915

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

浅谈Base64编码规则

Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,在了解Base64编码之前,先了解几个基本概念:位、字节。 位:"位(bit)"是计算机中最小的数据单位。每一位的状态只能是0或1; 字节:8个二进制位构成1个"字节(Byte)",字节是存储空间的基本计量单位。1个字节可以储存1个英文字母,2个字节可以存储1个汉字; Base64编码的作用 因为有些网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就不能通过邮件传送。这样就受到了很大的限制

jinglong512741的专栏 5153

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

浅谈Base64编码

转载:http://www.5dmail.net/html/2004-1-30/200413084348.htm 我打赌当你见到Base64这个词的时候你会觉得在哪里见过,因为在你能够上网看到这篇文章的时候你已经在后台使用它了。如果您对二进制数有所了解,你就可以开始读它了。 打开一封Email,查看其原始信息(您可以通过收取、导出该邮件用文本编辑器查看)。你会看到类似这样的一个效果:

Keep Moving 465

浅谈Base64编码算法

一、什么是编码解码   编码:利用特定的算法,对原始内容进行处理,生成运算后的内容,形成另一种数据的表现形式,可以根据算法,再还原回来,这种操作称之为编码。   解码:利用编码使用的算法的逆运算,对经过编码的数据进行处理,还原出原始数据,这种操作称之为解码。 二、什么是Base64编码算法   可以将任意的字节数组数据,通过算法,生成只有(大小写英文、数字、+、/)(一共6...

defukwanmcth26174的博客 201

浅谈Base64编码的原理

大家都知道,计算机最常用的存储方式都是用ASCII编码存储,然而有些情况下用ASCII编码来交换数据会造成错误,特别是ASCII中的控制字符,例如BS(退格),BEL(响铃)等,这些控制字符都是表示,当计算机碰到这些字符的时候要做出相应的动作,并不是普通的可打印字符。

Steven_2669的博客 572
上一篇: 类的静态常量初始化
下一篇: 【转】VC++中的图像类型转换--使用开源CxImage类库
code09
博客等级 码龄18年 31粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值