javascript实现base64格式转码与解码
最近碰到一个需求,后端返回base64格式的数据,前端需要进行base64格式解码,好了,前端采用内部提供的atob函数进行解码,开完成,交付测试,然后测试小哥哥小姐姐反馈说中文乱码!
然后查了一下,我后端代码采用utf8编码,这没问题,问题出在前端使用的atob函数,它居然采用的是Latin1(ISO-8859-1)编码!还不能修改编码方式,而且它还只在web端开发有这个atob函数!也不知道写这个atob函数的作者出于什么目的,Latin1(ISO-8859-1)编码用的很广么?竖中指!!!!
没办法,问题要解决,我们本可以找一下第三方的包,但想想,还是觉的自己实现一个转码的函数,留着备用,这里分享出来:
let base64util = function () {
let _keys = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
//base64格式加密
function encode(input) {
if (typeof input != "string") {
input = JSON.stringify(input)
}
//utf8转码,Unicode值转换为字节数组
let buffer = [];
for (var n = 0; n < input.length; n++) {
var c = input.charCodeAt(n);
if (c < 128) { //一个字节
buffer.push(c);
} else if (c < 2048) { //两个字节
buffer.push((c >> 6) | 192, (c & 63) | 128);
} else if (c < 65536) { //三个字节
buffer.push((c >> 12) | 224, ((c >> 6) & 63) | 128, (c & 63) | 128);
} else if (c < 2097152) { //四个字节
buffer.push((c >> 18) | 240, ((c >> 12) & 63) | 128, ((c >> 6) & 63) | 128, (c & 63) | 128);
} else if (c < 67108864) { //五个字节
buffer.push((c >> 24) | 248, ((c >> 18) & 63) | 128, ((c >> 12) & 63) | 128, ((c >> 6) & 63) | 128, (c & 63) | 128);
} else { //六个字节
buffer.push((c >> 30) | 252, ((c >> 24) & 63) | 128, ((c >> 18) & 63) | 128, ((c >> 12) & 63) | 128, ((c >> 6) & 63) | 128, (c & 63) | 128);
}
}
//转码,三字节转换成四字节
let i = 0, padding = buffer.length % 3;
padding && buffer.push(...new Array(padding = 3 - padding).fill(0));//先用0填补
let result = []
while (i < buffer.length) {
let [c1, c2, c3] = [buffer[i++], buffer[i++], buffer[i++]];
result.push(c1 >> 2, ((c1 & 0b11) << 4) | (c2 >> 4), ((c2 & 0b1111) << 2) | (c3 >> 6), c3 & 63);
}
padding && (result.splice(result.length - padding), result.push(...new Array(padding).fill(64)));//把0填补换成=
return result.map(v => _keys.charAt(v)).join("");
}
//base64格式解码
function decode(input) {
if (typeof input != "string") {
throw "invalid argument"
}
//解码,四字节转换成三字节
let buffer = input.split(""), i = 0, padding;
let r = []
while (i < buffer.length) {
let array = buffer.slice(i, i += 4).map(v => _keys.indexOf(v))
if (array.length != 4 || array.some(v => v < 0)) throw "invalid input"
padding = array.filter(v => v == 64).length;//获取填补的=号数量
padding && (array.splice(r.length - padding), array.push(...new Array(padding).fill(0)));//把=填补换成0
let [e1, e2, e3, e4] = array
r.push((e1 << 2) | (e2 >> 4), ((e2 & 15) << 4) | (e3 >> 2), ((e3 & 3) << 6) | e4);
}
padding && r.splice(r.length - padding)//去掉填补
//utf8转码,字节数组转换成Unicode值
i = 0;
buffer = [];
while (i < r.length) {
let c = r[i++]
if (c < 128) //一个字节
buffer.push(c);
else if (c < 224) //两个字节
buffer.push(((c & 31) << 6) | (r[i++] & 63));
else if (c < 240) //三个字节
buffer.push(((c & 15) << 12) | ((r[i++] & 63) << 6) | (r[i++] & 63));
else if (c < 248) //四个字节
buffer.push(((c & 7) << 18) | ((r[i++] & 63) << 12) | ((r[i++] & 63) << 6) | (r[i++] & 63));
else if (c < 252) //五个字节
buffer.push(((c & 3) << 24) | ((r[i++] & 63) << 18) | ((r[i++] & 63) << 12) | ((r[i++] & 63) << 6) | (r[i++] & 63));
else //六个字节
buffer.push(((c & 1) << 30) | ((r[i++] & 63) << 25) | ((r[i++] & 63) << 18) | ((r[i++] & 63) << 12) | ((r[i++] & 63) << 6) | (r[i++] & 63));
}
return buffer.map(v => String.fromCharCode(v)).join("");
}
return { encode, decode };
}()
使用:
//转码
base64util.encode("say:上山打老虎")
//解码
base64util.decode("c2F5OuS4iuWxseaJk+iAgeiZjg==")
结果:

javascript实现base64格式转码与解码的更多相关文章
- 把vux中的@font-face为base64格式的字体信息解码成可用的字体文件
在最近移动端项目中用到了vux,感觉用着还习惯,当把vux使用到PC端的时候出现了IE浏览器出现,这样的错误信息: CSS3114: @font-face 未能完成 OpenType 嵌入权限检查.权 ...
- javascript中base64和Gzip的使用
一般的使用流程(4步): 服务器端将字符串Gzip压缩为 字节数组——>通过base64转为字符串(后传递到客户端)——>解码base64字符串为字节数组——>Gzip解码字节数组为 ...
- javascript 使用btoa和atob来进行Base64转码和解码
javascript原生的api本来就支持,Base64,但是由于之前的javascript局限性,导致Base64基本中看不中用.当前html5标准正式化之际,Base64将有较大的转型空间,对于H ...
- JavaScript对HTML字符转义与反转义(转码和解码)
HTML的Encode(转码)和解码(Decode)在平时的开发中也是经常要处理的,在这里总结了使用javascript处理HTML的Encode(转码)和解码(Decode)的常用方式 一.用浏览器 ...
- Javascript中Base64编码解码的使用实例
Javascript为我们提供了一个简单的方法来实现字符串的Base64编码和解码,分别是window.btoa()函数和window.atob()函数. 1 var encodedStr = win ...
- javascript处理HTML的Encode(转码)和解码(Decode)
HTML的Encode(转码)和解码(Decode)在平时的开发中也是经常要处理的,在这里总结了使用javascript处理HTML的Encode(转码)和解码(Decode)的常用方式 一.用浏览器 ...
- base64格式的图片数据如何转成图片
base64格式的图片数据如何转成图片 一.总结 一句话总结:不仅要去掉前面的格式串,还需要base64_decode()解码才行. // $base_img是获取到前端传递的值 $base_img ...
- 图片64base转码与解码
场景一:图片转码成base64,传输,接收后解码成png等格式图片 import base64 # 读取图片,转换为base64编码格式 with open("F:\Archer\pictu ...
- html5 图片转为base64格式异步上传
因为有这个需求(移动端),所以就研究了一下,发现还挺不错的.这个主要是用了html5的API,不需要其他的JS插件,不过只有支持html5的浏览器才行,就现在而言应该大部份都支持的.<!DOCT ...
随机推荐
- Reactor之发射器(Flux、Mono)转换操作函数
数据合并函数 由于业务需求有的时候需要将多个数据源进行合并,Reactor提供了concat方法和merge方法: concat public static <T> Flux<T&g ...
- 使用springboot配置和注入数据源属性的方法和步骤
/** 1.书写一个名为resources/application.properties的属性文件---->书写一个配置属性类,类名为: **/ 文件:application.propertie ...
- 如何简单的理解LSTM——其实没有那么复杂(转载)
转载地址:https://www.jianshu.com/p/4b4701beba92 1.循环神经网络 人类针对每个问题的思考,一般不会是完全的从头开始思考.正如当你阅读这篇译文的时候,你会根据已经 ...
- C语言static关键字
C语言static关键字 static关键字的作用,主要从在程序的生存周期.作用域和在代码段中的位置起作用. 全局变量 静态全局变量 局部变量 静态局部量 生存周期 程序运行到结束 程序运行到结束 函 ...
- SpringBoot自定义控制层参数解析
一.背景 在Spring的Controller中,我们通过@RequestParam或@RequestBody就可以将请求中的参数映射到控制层具体的参数中,那么这个是怎么实现的呢?如果我现在控制层中的 ...
- 4个优化方法,让你能了解join计算过程更透彻
摘要:现如今, 跨源计算的场景越来越多, 数据计算不再单纯局限于单方,而可能来自不同的数据合作方进行联合计算. 本文分享自华为云社区<如何高可靠.高性能地优化join计算过程?4个优化让你掌握其 ...
- [BUUCTF]PWN4——pwn1_sctf_2016
[BUUCTF]PWN4--pwn1_sctf_2016 题目网址:https://buuoj.cn/challenges#pwn1_sctf_2016 步骤: 例行检查,32位,开启nx(堆栈不可执 ...
- [ZJCTF 2019]EasyHeap
目录 逆向分析 create 函数 edit 函数 delete 函数 利用思路 exp 脚本 get flag 内容来源 逆向分析 -------------------------------- ...
- CF447B DZY Loves Strings 题解
Content 有一个长度为 \(n\) 的仅含小写字母的字符串 \(s\) 以及 26 个英文小写字母的价值 \(W_\texttt{a},W_\texttt{b},...,W_\texttt{z} ...
- LuoguP7379 [COCI2018-2019#6] Lun 题解
Content 判断使一个长度为 \(n\) 的银行卡号码(有一个空缺)合法,空缺里面填入的最小数字. 数据范围:\(n\in[1,100]\). Solution 由于只有一个空缺,因此我们可以考虑 ...