WHAT - 最常用的 base64 数据编码方式(含 Blob 和 ArrayBuffer)

news2024/11/24 4:23:43

目录

  • 一、介绍
    • 1. Base64 的工作原理
      • Base64 字符集
      • Base64 编码基本原理
      • Base64 编码具体解释
    • 2. Base64 的编码示例
    • 3. Base64 的应用
      • 3.1 在 URL 中嵌入数据
      • 3.2 电子邮件附件
      • 3.3 数据传输
      • 3.4 存储与缓存
      • 总结
    • 4. 在 JavaScript 中使用 Base64
      • 编码
      • 解码
      • 使用 `Buffer` (Node.js)

一、介绍

Base64 是一种数据编码方式,用于将二进制数据转换为可打印的 ASCII 字符串。这种编码方式广泛用于在文本系统中传输二进制数据,比如在电子邮件中嵌入图像,或者在网络协议中传输复杂的数据。

// 123456
// 编码后
// MTIzNDU2

//hello
//编码后
//aGVsbG8=

1. Base64 的工作原理

Base64 字符集

Base64 字符集是一种用于将二进制数据编码为可打印的 ASCII 字符串的标准字符集。它包含 64 个字符,这些字符包括字母、数字以及两个特殊字符(通常是 +/,在 URL 和文件系统中有时会用不同的字符,如 -_)。

Base64 字符集的字符分布如下:

  1. 大写字母(A-Z):A 到 Z,代表值 0 到 25。
  2. 小写字母(a-z):a 到 z,代表值 26 到 51。
  3. 数字(0-9):0 到 9,代表值 52 到 61。
  4. 特殊字符:+ 代表值 62。/ 代表值 63。

这些字符用于表示 6 位二进制数。具体的字符集如下(在大多数 Base64 实现中):

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

Base64 编码基本原理

Base64 编码将每 3 个字节的原始二进制数据转换为 4 个可打印字符。

这是因为每个 Base64 字符表示 6 位数据(2^6 = 64),即 000000~111111,代表0~63,而 3 个字节是 24 位(3*8 = 24)。将 24 位数据分成 4 组,每组 6 位,从而产生 4 个 Base64 字符。

  • 原始数据:每 3 个字节 = 24 位。
  • Base64 编码:每 4 个字符 = 24 位。

Base64 编码具体解释

让我们更详细地解释一下 Base64 编码的过程,特别是为什么 3 个字节的二进制数据会转换为 4 个 Base64 字符。

  1. 字节与位的关系

    • 1 字节 = 8 位(bits)。
    • 3 个字节 = 3 * 8 = 24 位。
  2. Base64 字符表示

    • Base64 编码将二进制数据分成 6 位一组进行处理,因为 Base64 字符集包含 64 个不同的字符(2^6 = 64)。所以,每个 Base64 字符表示 6 位数据。
  3. 编码过程

    • 步骤 1: 从 3 个字节的二进制数据中提取 24 位数据。

    • 步骤 2: 将这 24 位数据分成 4 组,每组 6 位。

    • 步骤 3: 每 6 位数据通过 Base64 编码表(包含 64 个字符)映射成一个 Base64 字符。这就是为什么 3 个字节会被编码为 4 个 Base64 字符。

2. Base64 的编码示例

假设我们要编码字符串 “hello”:

  1. 原始数据

    • “hello” 的 ASCII 编码是 104 101 108 108 111
  2. 转换为二进制

    • 104 = 01101000
    • 101 = 01100101
    • 108 = 01101100
    • 108 = 01101100
    • 111 = 01101111
  3. 分组

    • 每 6 位分成一组,例如:
      011010 000110 010101 101100 011011 001111
      
  4. 编码

    • 这些 6 位组对应 Base64 字符,例如:
      011010 = 26 = a
      000110 = 6 = G
      010101 = 21 = V
      101100 = 44 = s
      011011 = 27 = b
      001111 = 15 = P
      
    • 最终编码结果是 “aGVsbG8=”。

注意:Base64 编码的结果可能会在末尾添加一个或两个 = 符号作为填充字符,用于确保数据长度是 4 的倍数。

3. Base64 的应用

下面是针对不同场景的 Base64 编码和解码示例,包括 URL 嵌入、电子邮件附件、数据传输和存储与缓存。我们将使用 JavaScript 代码来演示这些操作。

3.1 在 URL 中嵌入数据

场景描述:将图像数据通过 Base64 编码嵌入到 URL 中,例如用作 src 属性的值。

代码示例

假设我们有一个小的 PNG 图像文件,我们将其转为 Base64 字符串,然后在 HTML 中使用 Data URL 进行嵌入。

// 图像数据转换为 Base64 字符串的示例
function encodeImageToBase64(imageFile) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onloadend = () => resolve(reader.result);
    reader.onerror = reject;
    reader.readAsDataURL(imageFile);
  });
}

// 假设 imageFile 是 File 对象,例如通过 file input 获取的图像文件
const imageFile = document.querySelector('input[type="file"]').files[0];

encodeImageToBase64(imageFile).then(base64String => {
  console.log(base64String); // 输出 Base64 编码字符串
  // 使用 Base64 字符串作为图像的 src
  document.querySelector('img').src = base64String;
});

Base64 字符串示例

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAAC8GO2jAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHwAAAABJRU5ErkJggg==

3.2 电子邮件附件

场景描述:在电子邮件中嵌入图像或文档附件,Base64 编码用于将二进制数据嵌入邮件内容。

代码示例

// 将文件转换为 Base64 字符串
function convertFileToBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onloadend = () => resolve(reader.result);
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
}

// 假设 file 是要发送的文件,例如通过 file input 获取的文件
const file = document.querySelector('input[type="file"]').files[0];

convertFileToBase64(file).then(base64String => {
  // 在邮件中嵌入 Base64 数据
  const emailBody = `<img src="${base64String}" alt="Embedded Image">`;
  console.log(emailBody); // 输出邮件内容,通常由邮件客户端进行发送
});

Base64 字符串示例

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAAAAAAAD/2wBDAAoHBwkHBgoJCAkLCwoMDxkQDw4ODxwQEBwTGBYWFx0dIyIoIyIiIyIhJi4kIyIoNjo2LCYgJSYlLCYsMTExLCsyLC4vJjAqMygyNjo2N0FfJSMfFjM1M0YwYTMzLV0uMz5iFfAvfFwmMfJwNWUuLzP/2wBDAQsLC8rLC8wLjQ4MzUyMj8vM2QwP0PCZFBZXk5eXF9fX13lHUkLAw8xPD5dZHiMmYPk9fXYnKk2YJLc6MMPS9eK0YXEro6XjptH5ae/f1sZYqFjpLgWCyMuJUdFCOMqKIlC5Ti8gHjK0ePoNBe8aFSih+KTcCnEEw3zXyRYmrDmfMTlI6MYDFX/l5Y5r/mWq2Bf8XBLZfD4uYl2ziFthP6oyW8Onxw5WzNGxkL77B4u3D0+4ys...

3.3 数据传输

场景描述:通过 API 或网络协议将二进制数据转换为 Base64 字符串并进行传输。

代码示例

// 将二进制数据编码为 Base64 字符串
function arrayBufferToBase64(arrayBuffer) {
  let binary = '';
  let bytes = new Uint8Array(arrayBuffer);
  let len = bytes.byteLength;
  for (let i = 0; i < len; i++) {
    binary += String.fromCharCode(bytes[i]);
  }
  return window.btoa(binary);
}

// 假设我们从 API 获取到的二进制数据
fetch('https://example.com/api/data')
  .then(response => response.arrayBuffer())
  .then(arrayBuffer => {
    const base64String = arrayBufferToBase64(arrayBuffer);
    console.log(base64String); // 输出 Base64 编码字符串
    // 将 Base64 字符串发送到服务器或其他应用
  });

Base64 字符串示例

iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAAC8GO2jAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHwAAAABJRU5ErkJggg==

延伸

让我们详细解释一下为什么对从 API 获取的二进制数据进行上述格式转换:

  1. 从 API 获取响应数据

当你使用 fetch API 请求数据时,响应可以是多种格式,包括文本、JSON、Blob、ArrayBuffer 等。fetch 的默认响应格式是 ReadableStream,需要进一步处理来获取具体的数据格式。对于二进制数据,response.arrayBuffer() 是一种常见的选择。

  1. 转换为 ArrayBuffer

ArrayBuffer 是一种通用的、固定长度的原始二进制数据缓冲区。在 Web API 中,response.arrayBuffer() 方法将响应的原始数据转换为 ArrayBuffer 对象,这样可以更方便地处理二进制数据。

fetch('https://example.com/api/data')
  .then(response => response.arrayBuffer())
  .then(arrayBuffer => {
    // arrayBuffer 现在是原始的二进制数据
  });

注意,BlobArrayBuffer 都是 Web API 中用于处理二进制数据的两种重要数据结构,它们各自具有不同的用途和特性。主要区别在于:

  • 数据处理方式:ArrayBuffer 用于低级别的二进制数据处理,依赖视图(如 Uint8Array)来访问数据。Blob 用于高层次的数据处理,支持文件和流式操作。
  • 数据大小:ArrayBuffer 适用于处理固定大小的二进制数据。Blob 适用于处理任意大小的二进制数据块,可以是非常大的数据。
  • 数据用途:ArrayBuffer 通常用于处理来自网络请求的二进制数据,适合数据转换和操作。Blob 通常用于处理文件上传、下载和生成内容,适合文件和流的操作。
  1. ArrayBuffer 转换为 Base64 字符串

ArrayBuffer 本身是二进制的,而 Base64 是一种文本编码方式,用于将二进制数据转换为字符串格式。Base64 编码的好处包括:

  • 可嵌入文本环境:Base64 编码的字符串可以在 HTML、JSON、XML 等文本格式中嵌入和传输。
  • 数据传输:在某些协议或服务中,Base64 编码的文本数据更易于处理和传输。

转换步骤

function arrayBufferToBase64(arrayBuffer) {
  let binary = '';
  let bytes = new Uint8Array(arrayBuffer);
  let len = bytes.byteLength;
  for (let i = 0; i < len; i++) {
    binary += String.fromCharCode(bytes[i]);
  }
  return window.btoa(binary);
}
  1. ArrayBuffer 转 Uint8Arraynew Uint8Array(arrayBuffer)
    • Uint8Array 是一种视图,它允许我们以字节为单位访问 ArrayBuffer 的数据。

请添加图片描述

  1. Uint8Array 转 Binary StringString.fromCharCode()
    • Uint8Array 的每个字节转换为字符,并将这些字符组合成一个二进制字符串。因为 btoa 要求入参是二进制字符串。

请添加图片描述

  1. Binary String 转 Base64window.btoa()
    • 使用 window.btoa() 方法将二进制字符串转换为 Base64 编码的字符串。
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAADZ+foAAAAJcEhZcwAACxMAAAsTAdjz8gAAAHSiVHBtSFiaL3diNS1zYWUtYm5vODYAAAAyAAAAYAAAAPbAAAAASUVORK5CYII='

总结,每一步的转换都有其特定的用途:

  • ArrayBuffer 提供了对原始二进制数据的访问。
  • Uint8Array 使我们可以以字节为单位处理数据。
  • Binary String 是一种在 JavaScript 中处理二进制数据的中间格式。
  • Base64 编码将二进制数据转换为可嵌入文本环境中的字符串格式,便于传输和存储。

这些转换步骤确保了我们能够有效地处理和传输 API 返回的二进制数据,并将其转换为可以在不同场景中使用的格式。

3.4 存储与缓存

场景描述:将二进制数据(如图像)编码为 Base64 字符串并存储在浏览器的本地存储中。

代码示例

// 将图像数据存储到本地存储
function storeImageInLocalStorage(imageFile) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onloadend = () => {
      const base64String = reader.result;
      localStorage.setItem('storedImage', base64String);
      resolve();
    };
    reader.onerror = reject;
    reader.readAsDataURL(imageFile);
  });
}

// 从本地存储中读取图像数据并显示
function displayStoredImage() {
  const base64String = localStorage.getItem('storedImage');
  if (base64String) {
    document.querySelector('img').src = base64String;
  }
}

// 假设 imageFile 是 File 对象,例如通过 file input 获取的图像文件
const imageFile = document.querySelector('input[type="file"]').files[0];

storeImageInLocalStorage(imageFile).then(() => {
  displayStoredImage();
});

Base64 字符串示例(存储在本地存储中):

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAAC8GO2jAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHwAAAABJRU5ErkJggg==

总结

这些示例展示了如何在不同场景中使用 Base64 编码进行数据转换和处理:

  1. URL 中嵌入数据:将 Base64 编码的数据直接嵌入到 URL 中,如图像的 src 属性。
  2. 电子邮件附件:将二进制文件(如图像或文档)编码为 Base64 字符串,然后在电子邮件中嵌入。
  3. 数据传输:将二进制数据编码为 Base64 字符串,通过 API 或网络协议进行传输。
  4. 存储与缓存:将 Base64 编码的数据存储在浏览器的本地存储中,用于后续的读取和显示。

4. 在 JavaScript 中使用 Base64

编码

const str = "hello";
const encoded = btoa(str); // "aGVsbG8="
console.log(encoded);

MDN - btoa

解码

const encoded = "aGVsbG8=";
const decoded = atob(encoded); // "hello"
console.log(decoded);

MDN - atob

使用 Buffer (Node.js)

在 Node.js 中,你可以使用 Buffer 对象来进行 Base64 编码和解码:

// 编码
const buffer = Buffer.from('hello');
const encoded = buffer.toString('base64'); // "aGVsbG8="
console.log(encoded);

// 解码
const decodedBuffer = Buffer.from(encoded, 'base64');
const decoded = decodedBuffer.toString(); // "hello"
console.log(decoded);

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

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

相关文章

基于Python的重庆市气象数据分析可视化—计算机毕业设计源码24928

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对气象数据等问题&#xff0c;对气象信息进行…

大数据-112 Flink DataStreamAPI 程序输入源 DataSource 基于文件、集合、Kafka连接器

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

利用 Web 浏览器构建 Java Media Player

如果您需要在 Java 桌面应用程序中嵌入媒体播放器&#xff0c;有几种方法可供选择&#xff1a; 您可以使用 JavaFX Media API 来实现所有必需的媒体播放器功能。虽然稍显过时但仍然可用的 Java Media Framework 也可以作为一种解决方案。您可以集成像 VLCJ 这样的第三方 Java …

统计机器学习基础知识

一、统计机器学习定义 统计机器学习&#xff08;Statistical Machine Learning&#xff09;又称为统计学习&#xff08;Statistical Learning&#xff09;&#xff0c;是关于计算机基于数据构建概率统计模型并运用模型对数据进行预测与分析的一门学科&#xff0c;是概率论、统…

ET6框架(十)通讯消息编写

文章目录 一、消息在的定义&#xff1a;二、客户端消息的发送&#xff1a;三、服务器消息的处理&#xff1a;四、查看结果 一、消息在的定义&#xff1a; ET消息主要分为两类&#xff0c;一个种是普通消息&#xff0c;一种时通过Gate网关转发的消息叫Local消息 这里我们编写客…

【突发事件】Runway删库了,文章结尾有解决方法

最近&#xff0c;Runway 悄悄地从 Hugging Face 平台上删除了自己的代码库&#xff0c;其中包括备受瞩目的 Stable Diffusion v1.5 项目&#xff0c;这在科技界引起了轩然大波。 Runway 的行为不仅没有留下任何痕迹&#xff0c;也没有通知 Hugging Face 或任何社区成员。 更令人…

QEMU - user network

Documentation/Networking - QEMUQEMU/KVM中的网络虚拟化--Part2 User Networking | Xiaoye Zhengs blog (zxxyy.github.io)QEMU Network — ARM SoC Device Assignment Notes documentation (cwshu.github.io)slirp / libslirp GitLabGitHub - virtualsquare/libvdeslirp: li…

运用Premiere自学视频剪辑,这些岗位你能胜任!

随着短视频的兴起和火热&#xff0c;短视频后期制作越来越受到人们的重视&#xff0c;甚至衍生出很多岗位的高薪工作。如大家所了解的&#xff0c;Adobe premiere正是一款视频后期剪辑和制作工具&#xff0c;其功能强大&#xff0c;应用也十分广泛&#xff0c;是从事后期工作者…

【舞动生命,不缺营养!】亨廷顿舞蹈症患者的维生素秘籍✨

Hey小伙伴们&#xff5e;&#x1f44b; 在这个充满色彩的世界里&#xff0c;每个人都是独一无二的舞者&#xff0c;但对于患有亨廷顿舞蹈症的朋友来说&#xff0c;他们的舞蹈却多了几分挑战与不易。&#x1f4aa; 今天&#xff0c;就让我带你一起揭秘&#xff0c;那些能够助力亨…

机器学习/数据分析案例---糖尿病预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 这是一篇数据分析/机器学习很好的入门案例&#xff0c;对糖尿病的影响进行预测和分析通过随机森林预测&#xff0c;平均准确率和召回率都不错不足&#x…

Photomator 3.3.22 (macOS Universal) - 照片编辑软件

Photomator 3.3.22 (macOS Universal) - 照片编辑软件 适用于 Mac、iPhone 和 iPad 的终极照片编辑器 请访问原文链接&#xff1a;https://sysin.org/blog/photomator/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Photoma…

美发店拓客营销预约到店连锁小程序拓展

传统印象里的10元美发店&#xff0c;在城市里已然升级为大店&#xff0c;服务多样化&#xff0c;价格也是几十元到几千元不等数个区间&#xff0c;除了单店外也有连锁品牌进行区域拓展&#xff0c;以量和品牌形象收获更多客户和自身的宣传等。 尤其是规模相对较大的门店&#…

AcWing 896. 最长上升子序列 II

学习视频↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 【E04 线性DP 最长上升子序列 二分优化】 O ( n l o g n ) O(nlogn) O(nlogn) #include<iostream> #include<algorithm> #define N 100010 using namespace std; int n; int a[N],q[N]; i…

【软件工程】软件工程

考点2 软件工程 一、定义 二、软件工程基本原理 三、软件工程方法学&#xff08;范型&#xff09; 题目 选择题

数字乡村振兴智慧农业整体规划建设方案

1. 项目建设需求 《数字乡村振兴智慧农业整体规划建设方案》旨在通过遥感、物联网等技术&#xff0c;实现土地资源监测、测土配方施肥、农产品销售分析、农资监管、物流配送监管、农业专家库、市场分析、产业链应用和金融服务。 2. 项目需求分析 项目需求覆盖生产、经营、监…

关于计算机网络原理问题

2017年12月07日星期四&#xff0c; 问题&#xff1a; 答案&#xff1a; 接下来&#xff0c;我们来分析和解答&#xff0c; 首先&#xff0c;你要知道&#xff0c;一个byte&#xff08;字节&#xff09;能表示两个十六进制数&#xff0c;那么四个字节就可以表示8个十六进制数…

Simulink代码生成:关系运算与逻辑运算

文章目录 1 引言2 模块使用实例2.1 关系运算2.2 关系运算 3 代码生成4 总结 1 引言 在Simulink中经常需要判断两个信号的大小关系、是否相等&#xff0c;或者判断布尔类型信号的与、或、非等。本文研究通过关系运算与逻辑运算模块实现上述需求。 2 模块使用实例 2.1 关系运算…

hello树先生——二叉搜索树

文章目录 一.搜索二叉树的性质二&#xff0c;功能函数接口1.二叉树的节点结构&#xff0c;分为左右指针和数据2.二叉树的插入函数3.删除接口4.中序遍历 三.测试项目 一.搜索二叉树的性质 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值若它的右子树不…

uniapp scroll-view滚动触底加载 height高度自适应

背景&#xff1a; scroll-view组件是使用&#xff0c;官网说必须给一个高度height&#xff0c;否则无法滚动&#xff0c;所以刚开始设置了<scroll-view :style"height: 94vh" :scroll-y"true">设置了一个高度&#xff0c;想着vh应该挺合适的&#xf…

眼镜清洗机哪个品牌好?2024超声波清洗机推荐

眼镜作为日常生活不可或缺的配件&#xff0c;其卫生状况直接影响着我们的健康。日常简单的擦拭往往忽略了隐匿于镜片细微处的细菌群落&#xff0c;未彻底清洁的眼镜可能潜藏健康隐患。因此&#xff0c;深度清洁眼镜显得尤为关键&#xff0c;而超声波清洗机正是一种高效便捷的解…