讲字节数组转化为base64_Base64编码简介及简单实现

Base64编码是一种将字节数据编码为字符串的编码,字节数据会被编码成由64个可打印ASCII字符组成的字符串,这64个字符包括大写字母A-Z, 小写字母a-z, 以及数字 0 -9再加上 + 和 / ,刚好64个字符。对应的字符表如下图:

6792398d2612ea76e60488a7b098b5a2.png

base64编码的一个用途就是对http的头信息进行编码,由于http头信息使用ASCII编码,如果包含特殊字符可能会导致头信息解析异常,采用base64编码保证头信息只包含一些简单字符,提高了安全性。前端在显示图片元素时也经常会遇到base64编码的图片资源。

那么base64具体是如何进行编码的呢?

编码方式很简单,就是对目标字节中的每六个bit位表示为字母表中的某个字符,例如:

‘abc’对应的二进制字节为: 01100001 , 01100010 , 01100011 ; 每六位进行分组得到的结果如下:

011000, 010110, 001001, 100011,转化为10进制就是:24,22, 9, 35,根据上面的字母表得到各个数字对应的字符为:YWJj,所以abc最终会被编码为 ‘YWJj’。由于三个字节最终被编码成了四个字节的字符串,所以长度增加了1/3.

看着这里大家可能会有一个问题,假设原数据的字节长度不是3的倍数,就会有剩余的bit位不够6个字符,这是就会涉及到填充的问题,填充就是在原数据后面加上额外的冗余位,使数据的bit位长度刚好能被24(也就是3个字节)整除(6和8的最小公倍数)。具体的填充规则可以简单的表述为: 任何完全填充(不包含原始数据中的位) 的 6 位组都由特殊的第 65 个符号“=” 表示。 如果 6 位组是部分填充的, 就将填充位设置为 0(http权威指南)。

举个例子:假设在编码的过程中原数组有四个字节,这时就需要再填充2个字节。假设最后的两个bit为是10,填充后的数据的最后几位如下:

10 xxxx, xxxxxx,xxxxxx (x代表填充位)

根据前面描述的填充规则:第一个6位组对应的数字为 10 0000,后面两个由于时完全填充的,被编码为==,最终的结果的后三位就变成了‘g==’。

在浏览器端,可以调用全局的方法 atob 和 btoa 实现二进制字符与base64编码的字符之间的互相转化。下面给出一个base64编码前端实现的简单例子:

const table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';// 参数为待编码的字符串async function toBase64(str) {const blob = new Blob([str], { type: 'text/plain' });// 获取字节长度,也可以使用第三方库提供的同步方法// 这里为了演示简单const srcBuf = await blob.arrayBuffer();// 获取原数据的字节长度const length = blob.size;// 计算需要填充的位数const padLen = length % 3 === 1? 2: length % 3 === 2 ? 1 : 0;// 最终的长度const size = length + padLen;const arrBuf = new ArrayBuffer(size);const srcArray = new Uint8Array(srcBuf);const dstArray = new Uint8Array(arrBuf);for (let i = 0; i < size; i++) {if (i < length) {dstArray[i] = srcArray[i];} else {dstArray[i] = 0x00;}}let result = [];// 每次处理3个字节for (let i = 0; i < size; i += 3) {// 取出三个字节const a = dstArray[i];const b = dstArray[i + 1];const c = dstArray[i + 2];// 最后一组const isLast = i + 3 > length;console.log(padLen)result.push(a >> 2); // 第一个字节的前6位result.push(((a & 0b00000011) << 4) | (b >> 4)); // 第一个字节的后两位加上第二个字节的前四位// 第二个字节的后四位加上的三个字节的前两位if (!isLast || padLen === 0) {result.push(((b & 0b00001111) << 2) | (c >> 6));result.push(c & 0b00111111); // 第三个字节的后六位} else {if (padLen === 2) {result.push('=', '=');} else if (padLen === 1) {result.push(((b & 0b00001111) << 2) | (c >> 6), '=');}}}result = result.map(code => code === '=' ? '=' :        table[code]).join('');return result;}

base64转二进制字节原理类似,有兴趣的童鞋可以自行尝试!!

实际的运行效果如下图:

94fb4834b8b4e5aeca7f5b0a52c90faa.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/269763.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mybatis返回Map

返回一条记录的map resultType“map“ key就是列名&#xff0c;值就是对应的值 多条记录封装成一个map Select返回类型中是返回Map时&#xff0c;是对方法中是否存在注解MapKey&#xff0c;这个注解我也是第一次看到&#xff0c;当时我也以为是纯粹的返回单个数据对象的Map…

C# TreeView 连续点击 不触发AfterCheck事件

创建一个类 TreeView2 namespace System.Windows.Forms {public class TreeView2 : TreeView{protected override void WndProc(ref Message m){if (m.Msg ! 0x203){base.WndProc(ref m);}}} }然后前台放置一个TreeView控件。名叫&#xff1a;treeView1 后台代码&#xff1a; p…

最长等差数列_最长等差数列分析

原题给定未排序的数组&#xff0c;请给出方法找到最长的等差数列。分析题目描述比较简单&#xff0c;但是有一个问题我们需要首先搞清楚&#xff1a;等差数列中的数字&#xff0c;是否要和原始数组中的顺序一致。题目中&#xff0c;并没有说明&#xff0c;这个就需要大家在面试…

Mybatis中注解@MapKey的使用详解

MyBatis查询一些记录&#xff0c;数据涉及到两个表里的数据&#xff0c;需要连表查询&#xff0c;但我MyBatis的返回结果不想创建新的DO对象&#xff0c;因此使用MapKey注解返回一个Map集合。 含义&#xff1a;MapKey注解用于mapper.xml文件中&#xff0c;一般用于查询多条记录…

JMeter测试组件

JMeter的主要测试组件 1、测试计划是使用JMeter进行测试的起点&#xff0c;它是其它JMeter测试元件的容器。 2、线程组代表一定数量的并发用户&#xff0c;它可以用来模拟并发用户发送请求。实际的请求内容在Sampler中定义&#xff0c;它被线程组包含。 3、监听器负责收集测试结…

aes js 加盐值 解密_Java已有AES加解密,现需要前端Javascript加密调接口,返回的数据需要解密,目前互..._慕课猿问...

目前Javascript使用crypto-js包。前后台可以自己跑通加解密&#xff0c;但是&#xff0c;无法互通。针对对象{}加密……网上的方案&#xff0c;已经尝试了4天左右了&#xff0c;还没成功&#xff0c;请指导。无思路&#xff0c;无报错。Javapackage com.pactera.sms.foundbase.…

springboot 1.5.2 集成kafka 简单例子

添加依赖 compile("org.springframework.kafka:spring-kafka:1.1.2.RELEASE") 添加application.properties #kafka # 指定kafka 代理地址&#xff0c;可以多个 spring.kafka.bootstrap-servers192.168.59.130:9092,192.168.59.131:9092,192.168.59.132:9092 # 指定默…

更新 绑定数据_Blazor 修仙之旅 组件与数据绑定

一.前言在第一篇文章初尝 Blazor WebAssembly中&#xff0c;有提到过组件(Component)这个概念。组件在 Blazor 中是必不可少的&#xff0c;UI 全靠它组装起来&#xff0c;和前端的 JS 组件是一个意思&#xff0c;比如&#xff1a;vue component、react component 等等。借用官方…

Struts2 拦截器: 拦截器与过滤器区别

1、首先要明确什么是拦截器、什么是过滤器 1.1 什么是拦截器&#xff1a; 拦截器&#xff0c;在AOP&#xff08;Aspect-Oriented Programming&#xff09;中用于在某个方法或字段被访问之前&#xff0c;进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。…

关于使用idea工具debug时,断点颜色由红色变成灰色解决方法

在使用断点调试的时候&#xff0c;发现断点由原来的红色变成灰色的&#xff0c;后来发现是由于错误操作将Debug断点调试禁用了 &#xff0c;只需要点击禁用按钮取消就可以了

改变图标颜色_LOL设计师宣布修改装备图标:提高清晰度、颜色差异化

在11月12日&#xff0c;英雄联盟更新到了最新的季前赛版本。这次官方除了对部分英雄进行改动&#xff0c;主要是对于装备的图标和属性进行了更新。而在图标更新后&#xff0c;很多装备的样子都发生了很大的变化。这也导致很多老玩家在进游戏后&#xff0c;看着装备栏发呆&#…

虚拟机中centos安装gcc

yum install gcc-c 一、首先是&#xff1a;使得虚拟机联网 使用NAT模式 虚拟机网络连接使用NAT模式&#xff0c;物理机网络连接使用Vmnet8。 虚拟机设置里面——网络适配器&#xff0c;网络连接选择NAT模式。 虚拟机菜单栏—编辑—虚拟网络编辑器&#xff0c;选择Vmnet8 NAT模式…

python查看汉字的编码_python有关汉字编码问题

python分为&#xff1a;程序编码(python安装程序)、文件编码。查看程序编码方式&#xff1a;sys.getdefaultencoding()查看文件编码方式&#xff1a;1.import chardet 2. f open(lianxi1-qus.py) data f.read() print chardet.detect(data)字符编码发展历程&#…

gcd(欧几里得算法)

基础 1 int gcd(int a,int b) 2 { 3 int r; 4 while(b>0) 5 { 6 ra%b; 7 ab; 8 br; 9 } 10 return a; 11 } View Code递归 1 int gcd(int a,int b) 2 { 3 return (b>0)?gcd(b,a%b):a; 4 } Vi…

网络摄像头sdk_SenseDLC嵌入式人像识别SDK 安防边缘的“小巨人”

随着这些年将人工智能技术赋能行业的不断深入&#xff0c;商汤科技对智慧城市建设有着更深的理解。通过不断实践发现&#xff0c;很多区域由于摄像头数量和布置等问题较难有效做到清晰的人脸抓拍&#xff0c;且单一的人脸识别会遇到诸多干扰&#xff0c;比如发型、胖瘦、年纪、…

使用最大似然法来求解线性模型(1)

在Coursera机器学习课程中&#xff0c;第一篇练习就是如何使用最小均方差(Least Square)来求解线性模型中的参数。本文从概率论的角度---最大化似然函数&#xff0c;来求解模型参数&#xff0c;得到线性模型。本文内容来源于&#xff1a;《A First Course of Machine Learning》…