玩转代码|JS实现中文字符串对utf-8的Base64编码的方法

news2024/10/7 10:19:10

目录

UTF-8 字符串编解码

解决方法

解析

utf8_to_b64

b64_to_utf8

弃用 unescape 和 escape 方法

原由

解决方法

Node.js 下的 Base64 编解码


Base64 编解码

Base64是一种使用64基的位置计数法。它使用2的最大次方来代表仅可打印的ASCII 字符。这使它可用来作为电子邮件的传输编码。在Base64中的变量使用字符A-Z、a-z和0-9 ,这样共有62个字符,用来作为开始的64个数字,最后两个用来作为数字的符号在不同的系统中而不同。一些如uuencode的其他编码方法,和之后binhex的版本使用不同的64字符集来代表6个二进制数字,但是它们不叫Base64。

 

其实在 JavaScript 中,原生就有两个函数被分别用来处理解码和编码 base64 字符串:

  • btoa(): 从二进制数据的 “字符串” 创建一个 Base64 编码的 ASCII 字符串(“btoa” 其实是 “二进制转 ASCII” 的意思)。
  • atob(): 解码 Base64 编码的字符串(“atob” 其实是 “ASCII 到二进制” 的意思)。

 

可以通过 window.atob(string)window.btoa(base64string) 的方式调用,非常方便。

UTF-8 字符串编解码

UTF-8(8位元,Universal Character Set/Unicode Transformation Format)是针对Unicode的一种可变长度字符编码。它可以用来表示Unicode标准中的任何字符,而且其编码中的第一个字节仍与ASCII相容,使得原来处理ASCII字符的软件无须或只进行少部分修改后,便可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。

 

如上面的描述所言,btoa 和 atob 都只支持 ASCII 字符,并不支持 Unicode 字符。在大多数浏览器中对 Unicode 字符串调用将会报 Character Out Of Range 错误,因为字符超出了 ASCII 的范围。

解决方法

我们可以将字符串转义过后再进行编码,解码时将解码结果重新转义为 Unicode 字符串。

function utf8_to_b64(str) {
  return btoa(unescape(encodeURIComponent(str)));
}

function b64_to_utf8(str) {
  return decodeURIComponent(escape(atob(str)));
}

// 用例:
utf8_to_b64("测试"); // "5rWL6K+V"
b64_to_utf8("5rWL6K+V"); // "测试"

解析

这中间看起来比较神奇,发生了个什么事呢?

主要呢就是利用了 encodeURIComponentdecodeURIComponent 会把接受到的字符串参数当作 UTF-8 字符串来进行处理。

utf8_to_b64

先看 utf8_to_b64 方法。

这里由于 encodeURIComponent 方法接受的是 UTF-8 字符串,可以先用 encodeURIComponent 方法将 UTF-8 字符串转成了形如 %XX%XX 的十六进制符号。然后使用 unescape 方法将十六进制翻译为了 ASCII 中对应的内容,这样就变成了 btoa 方法能够接受的 ASCII 字符串。最后直接使用 btoa 方法编码为 Base64 字符串。

encodeURIComponent("测试"); // "%E6%B5%8B%E8%AF%95"
unescape("%E6%B5%8B%E8%AF%95"); // "æµ\x8Bè¯\x95"
btoa("æµ\x8Bè¯\x95"); // "5rWL6K+V"

总的来说就是一个将 UTF-8 字符串转为 ASCII 字符串再编码的一个过程。

b64_to_utf8

再看 b64_to_utf8 方法。

其实就是反过来,先将 Base64 字符串通过 atob 方法解码为 ASCII 字符串,然后通过 escape 方法将 ASCII 字符串转为十六进制符号,最后将十六进制符号通过 decodeURIComponent 方法解析为 UTF-8。

atob("5rWL6K+V"); // "æµ\x8Bè¯\x95"
escape("æµ\x8Bè¯\x95"); // "%E6%B5%8B%E8%AF%95"
decodeURIComponent("%E6%B5%8B%E8%AF%95"); // "测试"

弃用 unescape 和 escape 方法

原由

该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性。

可以看到 unescape 和 escape 方法已经被标记为废弃,并推荐使用 decodeURI 或 decodeURIComponent 替代 unescape,推荐使用 encodeURI 或 encodeURIComponent 替代 escape

根据百分号编码 - 维基百科中的内容可以知道,escape 在处理 0xff 之外字符的时候,是直接使用字符的 unicode 在前面加上一个 「% u」,而 encodeURI 则是先进行 UTF-8,再在 UTF-8 的每个字节码前加上一个 「%」

2005 年 1 月发布的 RFC 3986,建议所有新的 URI 必须对未保留字符不加以百分号编码;其它字符建议先转换为 UTF-8 字节序列,然后对其字节值使用百分号编码。此前的 URI 不受此标准的影响。
有一些不符合标准的把 Unicode 字符在 URI 中表示为: %uxxxx, 其中 xxxx 是用 4 个十六进制数字表示的 Unicode 的码位值。任何 RFC 都没有这样的字符表示方法,并且已经被 W3C 拒绝 (页面存档备份,存于互联网档案馆)。第三版的 ECMA-262 仍然包含函数 escape(string) 使用这种语法,但也有函数 encodeURI(uri) 转换字符到 UTF-8 字节序列并用百分号编码每个字节。

所以 escape 是对百分号编码的非标准实现,所以被废弃实属正常。

解决方法

虽说 escape 是对百分号编码的非标准实现,但是在上面的方法中我们实际上利用了 escape 的这种特性,这边提供了不使用 unescape 和 escape 方法后的实现。

function utf8_to_b64(str) {
  return btoa(
    encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
      return String.fromCharCode("0x" + p1);
    })
  );
}

function b64_to_utf8(str) {
  return decodeURIComponent(
    atob(str)
      .split("")
      .map(function (c) {
        return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
      })
      .join("")
  );
}

// 用例:
utf8_to_b64("测试"); // "5rWL6K+V"
b64_to_utf8("5rWL6K+V"); // "测试"

Node.js 下的 Base64 编解码

在 Node.js 中使用上面的方法,你可能会发现,btoa 和 atob 方法,由于只支持 ASCII 方法也已经被标记为废弃了,那么在 Node.js 中用什么方法呢?

Node.js 中提供了一个更加简便的方法,那就是利用 Buffer,除了支持字符串,也支持其他数据。

function utf8_to_b64(str) {
  return Buffer.from(str).toString("base64");
}

function b64_to_utf8(str) {
  return Buffer.from(str, "base64").toString("utf8");
}

 

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

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

相关文章

YOLOv2论文对比总结

1、高分辨率图片效果提升 2、Anchor 3、Loss函数 4、小目标友好

【文献分享】比目前最先进的模型轻30%!高效多机器人SLAM蒸馏描述符!

论文题目:Descriptor Distillation for Efficient Multi-Robot SLAM 中文题目:高效多机器人SLAM蒸馏描述符 作者:Xiyue Guo, Junjie Hu, Hujun Bao and Guofeng Zhang 作者机构:浙江大学CAD&CG国家重点实验室 香港中文大学…

Windows安装Redis(配置开机自启+配置密码)

Windows安装Redis 背景安装配置开机自启补充: 在Windows中配置jar自启动 设置密码暂时永久(推荐) 背景 Redis以其优异的性能备受青睐. 成为开发人员离不开的软件一直, 相信愿意点开观看此文的人DDDD 最近因为需要在Windows服务器上面搭建各种项目运行环境, 其中就包括Redis 因…

vue 实现课程表甘特图

1 封装 components <template><view style"padding-bottom: 100rpx;"><view class"header flex_sb"><div class"header_list flex" v-for"(item,index) in timeList" :key"item.value"><div&g…

CORS跨域资源共享漏洞

前置知识 跨域 域&#xff08;Domain&#xff09;是由三部分组成的标识&#xff1a;协议、域名和端口。 例如这两个ip就属于不同的域&#xff1a; http://example.com https://example.com 因为它们的协议不同&#xff08;一个是HTTP&#xff0c;另一个是HTTPS&#xff0…

2023百强县名单出炉!千亿县达54个

作为国民经济发展中的基本单元&#xff0c;县域经济发挥着重要作用。 赛迪顾问25日发布的《2023中国县域经济百强研究》&#xff08;下称“报告”&#xff09;显示&#xff0c;千亿县达54个&#xff0c;百强县前10名中江苏省独占6席。 在百强县前10名中&#xff0c;江苏省占席最…

Esp32_Arduino接入腾讯云笔记

ESP32是一款由乐鑫科技&#xff08;Espressif Systems&#xff09;推出的双核、低功耗、集成Wi-Fi和蓝牙的单芯片微控制器。它采用了Tensilica Xtensa LX6高性能处理器&#xff0c;具有大量的GPIO引脚、模数转换器、SPI、I2S、UART、PWM、I2C和SD卡接口等功能&#xff0c;可以满…

android 清除缓存方法

获得应用的存储信息 private void getAppStorageInfo(String packageName){StorageStatsManager storageStatsManager (StorageStatsManager) context.getSystemService(Context.STORAGE_STATS_SERVICE);StorageManager storageManager (StorageManager) context.getSystemS…

第二十一章 数据处理篇:imgaug

参考教程&#xff1a; https://imgaug.readthedocs.io/en/latest/source/jupyter_notebooks.html 文章目录 概述针对图片的增强基础使用样例base class: augment增强的组合sequentialsomeof和oneofsometimes 增强的种类 针对关键点的增强针对包围框的增强 概述 imgaug是一个使…

【深度学习】GPT-3

2020年5月&#xff0c;OpenAI在长达72页的论文《https://arxiv.org/pdf/2005.14165Language Models are Few-Shot Learners》中发布了GPT-3&#xff0c;共有1750亿参数量&#xff0c;需要700G的硬盘存储&#xff0c;(GPT-2有15亿个参数)&#xff0c;它比GPT-2有了极大的改进。根…

PX4常见解锁失败报错及解决方法

文章目录 一、Kill switch engagen二、电源检查CBRK_SUPPLY_CHK三、USB连接检查CBRK_USB_CHK四、安全开关检查CBRK_IO_SAFETY五、high Accelerometer bios六、high gyro bios七、compasss inconsistent八、GPS报错九、Accels inconsistent十、偏航角一直漂移十一、PREFLIGHT FA…

同步编程和异步编程的区别

我在这里用几个例子&#xff08;附带图文&#xff09;给你们讲解一下&#xff0c;具体区别。 第一个例子 一、同步 执行步骤&#xff1a; step1 》 step2 》step3 先打印 hello moon&#xff0c; 再打印图片&#xff0c; 等待图片打印完&#xff0c;再打印 hello Jupiter …

全国青少年信息素养大赛Scratch图形化编程_初赛_模拟一卷

全国青少年电子信息智能创新大赛Scratch图形化编程_初赛_模拟一卷 一、选择题 第 1 题 单选题 能让角色在整个舞台范围内的任意位置出现的程序是&#xff1f;&#xff08; &#xff09; A. B. C. D. 第 2 题 单选题 猫抓老鼠游戏的封面上有“开始”按钮和“游戏规则”两…

实战:Docker+Jenkins+Gitee构建CICD流水线

文章目录 前言Jenkins部署创建Jenkins docker-compose配置maven源启动Jenkins容器安装插件Gitee ssh公匙配置与测试项目提交 Jenkins创建流水线写在最后 前言 持续集成和持续交付一直是当下流行的开发运维方式&#xff0c;CICD省去了大量的运维时间&#xff0c;也能够提高开发…

Windows环境部署安装Chatglm2-6B-int4

chatglm2-6B是最近比较火爆的大模型&#xff0c;可以在消费级显卡上部署使用&#xff0c;适合学习。但是一般人也不一定有那么高的硬件配置&#xff0c;所以部署个int4版本应该是大多数人的最好选择。我就在家里部署起了int4版本的chatglm2-6B&#xff0c;记录一下免得忘了。 …

Docker资源限制

Docker资源限制 一、cpu资源控制1、 设置cpu使用率上限2、设置cpu资源占用比&#xff08;设置多个容器时才有效&#xff09;3、设置容器绑定指定的CPU 三、内存资源控制四、磁盘IO配额控制1、限制Block IO2、限制bps和iops进行限制 一、cpu资源控制 cgroups是一个非常强大的li…

VMware虚拟机无法自动获取IP地址的解决办法

安装好虚拟机后&#xff0c;网络是ok的&#xff0c;但是关机后&#xff0c;再次开启就不能用了。网上找了好多方法&#xff0c;都不管用&#xff0c;最后恢复默认设置搞定了&#xff0c;实在没办法的可以试一试

【致敬未来的攻城狮计划】第3期 作业汇总贴 + 获奖公布(文末荐书)

目录 一、写在前面 二、种子学员介绍 三、作业贴汇总 四、小小总结 五、获奖公布 六、学员有话说 七、特别致谢 八、友情荐书 一、写在前面 时间过得真快&#xff0c;距离 【致敬未来的攻城狮计划】第3期 的发起&#xff0c;已经过去有些时间了&#xff0c;让我们一起…

FileHub使用教程:Github Token获取步骤,使用快人一步

FileHub介绍 filehub是我开发的一个免费文件存储软件&#xff0c;可存万物。软件仓库&#xff1a;GitHub - Sjj1024/s-hub: 一个使用github作为资源存储的软件 软件下载地址&#xff1a;。有问题可以留言或者提Issue&#xff0c; 使用第一步&#xff1a;获取Github Token 使…

苹果手机充电充不进去什么原因?2023最新解决方法!

最近新买了一部苹果手机&#xff0c;才开心没两天呢&#xff0c;今天突然就发现苹果手机充电充不进了&#xff0c;这是为什么呢&#xff1f;有没有朋友知道呀&#xff1f;” 苹果手机作为目前年轻人比较喜欢的一款手机&#xff0c;也渐渐走进我们的生活。但在使用苹果手机时&am…