讲字节数组转化为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…

Mybatis中注解@MapKey的使用详解

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

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

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

关于使用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模式…

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》…

.net aspose.words 域加载图片_使用Python批量替换csdn文章的图片链接

欢迎大家关注我的微信公众号“IT工匠”获取更多资源(涉及算法、数据结构、java、深度学习、计算机网络、python、Android等互联网技术资料)。前言笔者之前的写作习惯一直是在本地(MacTyporaIpac)写好之后将markdown代码粘贴到csdn&#xff0c;图片是Ipac自动上传到微博匿名图床…

基恩士上位机链路通讯_基恩士PLC通讯源码

基恩士PLC KV7000,8000还是比较好用的&#xff0c;那如何和上位机通讯&#xff0c;我把源码写出来了。采用上位链路通讯&#xff0c;基恩士官方给我们留了8501端口,这个端口有意思刚好是我生日。基恩士的资料我觉得做的特别好&#xff0c;能快速写源代码得益于官方资料特别详细…

fastq质量值_fastq 数据格式解析

概念介绍Read 读段Read 中文翻译&#xff1a; 读段&#xff0c;来自测序仪的raw data一个Read 可能由多个片段组成&#xff0c; Read的索引是测序时的顺序Sequencing quality 测序质量测序仪在测序的时候&#xff0c;每次测出来的结果可能都不一样(仪器误差 序列长度等各方面因…

画像分析(3-3)标签建模-模型管理-新建关系

1、关系是什么 关系&#xff0c;是实体与实体之间所发生的连接&#xff0c;通常表示某一种行为/一个事实&#xff0c;如成交、搜索、出行。从数据表的角度来看&#xff0c;这样的表通常被称为”事实表“&#xff0c;往往是有多个联合主键&#xff08;或是说都是外键&#xff09…

二进制、八进制、十进制、十六进制之间的转换

在计算机语言中常用的进制有二进制、八进制、十进制和十六进制&#xff0c;十进制是最主要的表达形式。 对于进制&#xff0c;有两个基本的概念&#xff1a;基数和运算规则。 基数&#xff1a;基数是指一种进制中组成的基本数字&#xff0c;也就是不能再进行拆分的数字。二进…