HarmonyOS Next 将ArrayBuffer压缩到指定大小并转化为base64返回
项目中有需求要对获取的图片进行压缩,并且是要压缩到固定大小,考虑到harmonyos中对图片质量压缩方式packing,压缩后要及时检查大小,就使用while循环一步步的压缩,直至压缩到目标值
let bitmap: ArrayBuffer;// 需要压缩的数据
let compressSize: number;// 目标大小
let considerBase64: boolean;// 是否考虑base64算法把字节数扩大4/3倍的影响
let result=\’\’;
if (bitmap){
try {
let imageSource = image.createImageSource(bitmap);
let packer = image.createImagePacker();
let packerData = await packer.packing(imageSource,{
format: \’image/jpeg\’.
quality: 100
}):
if (considerBase64 && compresssize > 0){
compresssize = Math.ceil(compressSize * 3.0 / 4.0 -0.5);
}
let optionQuality = 90:
while (compresssize > 0
&& packerData.byteLength / 1024 > compresssize
&& optionQuality > 0) {
let whilePacker = image.createImagePacker();
let whileImageSource = image.createImageSource(packerData);
packerData = await whilePacker.packing(whileImageSource,{
format: \’image/jpeg\’,
quality: optionQuality
});
optionQuality -= 10;
}
result = buffer.from(packerData).tostrinl(\’base64\’);
} catch (error){
hilog.error(0x0000, \’error: \’ + JSOM.stringify(error), \’%{public}s\’);
}
}
—————– end —————
后面会继续补充不足之处。
系统性学习 Nodejs(4)——Buffer
在 Node 中,我们总是会遇到处理二进制数据的情况,比如文件操作、图片处理、网络 IO 等等。为了能够处理二进制数据,Node 引入了 Buffer。
归根结底,Buffer 是一个存储二进制数据的特殊对象,它对外暴露了操作二进制数据的能力。
计算机是如何存储数据的
非科班出身的程序员可能对二进制都非常陌生,这里简单的科普一下,以助于更好的理解 Buffer,了解这方面的同学可以直接略过。
计算机的存储单位
- bit(位):最小的存储单位,1 位只能存储一个 0 或 1。
- byte(字节):计算机的基本存储单位,由 8 位组成。
- 字:计算机进行数据处理时,一次存取、加工和传送的数据长度称为字。常说的 64 位操作系统即是说,一次可以操作 64 位(8 字节)的数据。这里的 64 位称为一个字。
如下图所示,一个每个方格即是 1 位,8 个方格即是 一个字节。
原谅我这丑陋的画图技术。
如何存储数字
我们常见的数字进制有 10 进制、8 进制、16 进制。
以 10 进制为例:数字 8 转换为 2进制为 , 其存储结构大概如下图所示。
一个基本存储单元为 1 字节即 8 位,而这里只有 4 位,空余 4 位都补 0.
这里只是大概的描述,js 具体的存储规则遵循 IEEE 754 规范
如何存储英文
根据 ASCII 表将每个字符对应的 ASCII 值转成二进制存储到计算机中。
ASCII 表如下图所示:
、
举个例子:
一个字母 A 对应的 ASCII 码为 81,81 对应的二级制为 1010001,所以其存储结构为:
0 0 1 0 1 0 0 0 1
如何存储汉字
一般都会根据 GBK 规范,将每个汉字转换成对应的编码,类似于 ASCII 码,只不过比它更复杂点。根据 GBK 编码,一个汉字占两个字节。毕竟汉字多嘛,一个字节肯定表示不了(因为一个字节最多能表示 2^8 – 1 即 255 个字符)。
如何存储所有字符
目前英文跟汉字都可以存储了,但是当两种字符都存在的情况下,我该按照哪种规范去编码呢?
- Unicode
这是 Unicode 国际组织用来容纳世界上所有字符的一个编码规范,它是一个字符集,包含了所有字符。由于编码众多,所以采用 4 个字节表示。
如果它仅是一个英文字符的话,就会白白浪费 3 个字节的空间(英文字符只占 1 字节的空间),所以浪费了极大的内存。
- utf-8
它是针对 Unicode 的一种可变长度字符编码,可以用来表示Unicode标准中的任何字符。它会根据不同的语言字符采用不同的字节数去编码,所以完美解决了 Unicode 字符集的问题。
使用 Buffer
OK OK OK
圆规正转,让我们进入正题。
使用 Buffer.from(string) 创建一个 Buffer 实例。
可以看到我们打印的是个 Buffer 的实例,但是奇怪的是这个实例展示的并不是我们所说的 2 进制,而十 16 进制。
这是为了方便我们查看,Node 在显示的时候,给转换成了 16 进制,其实内部仍然是 2 进制。
Buffer.from(string) 支持多种编码方式。
如上所示,可以将字符串以 ASCII 码的方式转成对应的二进制 Buffer。打印的时候,可以用任何编码方式去查看。
Node 目前支持的编码方式有:
- ascii
- utf8
- utf16le – 2 或 4 个字节,小字节序编码的 Unicode 字符。支持代理对(U+10000 至 U+10FFFF)。
- ucs2 – utf16le 的别名。
- base64 – Base64 编码。
- latin1 – 一种把 Buffer 编码成一字节编码的字符串的方式。
- binary – latin1 的别名。
- hex – 将每个字节编码为两个十六进制字符。
Buffer.from(array|arrayBuffer|buffer)Buffer.alloc(size[, fill[, endcoding]])
返回一个指定大小的 Buffer 实例,如果没有设置 fill,则默认填满 0。
Buffer.allocUnsafe(size)
返回一个没有被初始化的 Buffer,由于没有内存没有被初始化,所以可能含有一些其它的数据。
写入 Buffer
buf.write(string[, offset[, length]][, encoding])
参数描述:
- string:写入 buffer 的字符串
- offset:开始写入 buffer 的索引值,默认为 0
- length:写入 buffer 的长度
- encoding: 写入 buffer 字符串的字符编码
返回值:
返回实际写入的长度
读取 Buffer
buf.toString([encoding[, start[, end]]])
参数:
- encoding – 使用的编码。默认为 \’utf8\’ 。
- start – 指定开始读取的索引位置,默认为 0。
- end – 结束位置,默认为缓冲区的末尾。
合并 Buffer
Buffer.concat(list[, totalLength])
- list – 用于合并的 Buffer 对象数组列表。
- totalLength – 指定合并后Buffer对象的总长度。
返回值:返回多个成员合并的新 Buffer 对象。
裁剪 Buffer
buf.slice([start[, end]])
- start – 数字, 可选, 默认: 0
- end – 数字, 可选, 默认: buffer.length
返回值:返回一个新的 Buffer,它与旧的 Buffer 执行同一块内存。
以上就是 Buffer 的常用方法,更多的方法可以查看 Node 的官方文档。
Buffer 有什么用?
说了这么多,那 Buffer 到底有什么用呢?我们举个简单的例子。
假如让我们实现一个文件拷贝的功能,即把文件 A 复制到文件 B,我们要怎么做?
- 读取文件 A
- 将文件 A 的内容写入到文件 B
所以我们很容易写出这样的代码。
对 fs 不熟悉的朋友我先简单介绍一下,详细介绍会在下一篇文章给出。 fs.readFile: 读取文件 fs.writeFile: 写入文件
这里我们很轻松的实现了文件的拷贝,但是这里有个很严重的问题:读取的文件是一次性的写入到内存,如果我们的文件很大,比如有 8g,而我们的内存只有 4g,那电脑直接卡死,这显然不是我们想要的效果。
那我们该如何解决这个问题呢?
这时候我们就可以用 Buffer。每次读取的时候我们可以控制读取的大小,比如 4 字节。读完 4 字节之后,将这部分内容写入到 Buffer,然后再从 Buffer 写入到文件内。所以现在的步骤大概是这样:
- 从 A 内读取 4 字节内容
- 将这 4 字节内容写入到 Buffer
- 将 Buffer 内的内容写入到文件 B
- 重复上述步骤直到复制完成
这样我们就完美解决了这个问题,完整代码如下:
不熟悉的文件操作的同学不要着急,我下篇文章会专门介绍,这里先了解思路即可。 其实,这也是 流(stream) 的核心思路
如果你阅读完此文能够对你有帮助,希望能得到你的点赞认可。
这是系统性学习 Nodejs 的第四篇内容,后续会持续输出,如果感兴趣,欢迎关注我的专栏。
腾讯安全玄武实验室首次公开CPU漏洞利用全过程
中新网7月23日电 年初公开的CPU漏洞危机仍在持续发酵,近日有安全人员再次发现漏洞的变种,并因此获得英特尔10万美元奖励。但不少用户对该漏洞却产生“狼来了”的错觉:第一,尽管\”Spectre\”影响了大量的用户,但它能否在实际的攻击中产生危害?第二,截至目前仍然没有一例利用该漏洞发起攻击的事件汇报。
腾讯安全玄武实验室打破了这个错觉。在7月21日“2018看雪峰会”上,实验室高级研究员宋凯首度分享了如何在浏览器中利用\”Spectre\”漏洞,并通过JS 触发\”Spectre\”漏洞生成可以稳定刷新缓存的汇编指令。除此之外,宋凯还分享了在浏览器中,通过 \”Spectre\” 漏洞可能造成的实际危害,及相关的缓解措施。
2018安全开发者峰会由行业老牌安全技术社区——看雪学院主办,会议面向开发者、安全人员及高端技术从业人员,是国内开发者与安全人才的年度盛事。腾讯安全作为本次峰会的钻石级赞助单位,携四大业务矩阵亮相现场,展现了以腾讯安全联合实验室七大国际顶尖白帽黑客为能力核心构建的人才+技术的业务模式,受到在场行业人士的广泛关注。
毫无疑问,\”Spectre\” 是一个严重的CPU漏洞,打破了不同应用程序之间的隔离,影响了大部分的主流架构。它允许攻击者欺骗无错程序,且攻击者可以通过缓存来利用这个漏洞,泄漏用户级进程中的敏感数据。大部分公开的攻击,都是本地攻击。如果可以通过浏览器进行漏洞利用,那么对用户的大规模攻击将成为可能。由于浏览器用户量庞大,若攻击成功,结果将不堪设想。
“理论上,这个漏洞对个人用户最主要的危害相当于一个跨平台跨浏览器的超级 UXSS。但实际能否实现?能多大程度上实现?大家心里都没数。”CPU漏洞公开的第五天,腾讯安全玄武实验室负责人于旸(TK教主)在微博上公开了实验室这段时间“沉寂”的成果——研发了一个可以检测用户浏览器是否易遭受攻击的在线检测工具。
企业用户可借助该工具实时检测浏览器安全状态。若检测结果表明浏览器易于遭受攻击,则说明风险真实存在。宋凯在现场还分享了这个工具上线后的“意外”,“当时这个漏洞工具发布之后也算是全球首发的在线检测工具,为数以千计的用户检查出了自己设备中的问题。比较出乎意料的是,因为我们最开始的测试环境有限,只在一些Windows机器上测试了Chrome浏览器相关的漏洞,发布了之后发现竟然不同的设备都会被影响,比如SurfacePro、MacOS、iPhoneX、Pixel 2等。”
在线检测工具只是开始。“未知攻,焉知防”,摸清利用“Spectre”漏洞发起攻击的方式才是腾讯安全玄武实验室这群白帽黑客的研究重点。
宋凯在演讲中表示,这个漏洞的根本原因是因为推测执行中的代码可以影响CPU的缓存,而这个缓存的影响又可以用一些技术手段探测出来。分支逻辑在这种实践上是不可靠的,因为缓存被影响了,它可以让攻击者推测出预测执行中所访问数据的内容,并且这个数据是可以测量的,就可以进一步的泄露了。
于是如何稳定的刷新缓存,以及如何保证在利用过程中特定的数据不出现在缓存中,是在浏览器其实现漏洞攻击首先需要解决的问题。腾讯安全玄武实验室的做法是,先访问大量不同的地址来强制刷新缓存,实现缓存刷新的功能,再通过将变量放在不同的内存中来遍历的方式,保证每一次遍历的变量都不在缓存中。同时,通过Worker+SharedArrayBuffer可以做到相对预测内存访问时间的精度计时器,通过动态遍历缓存大小的方式用来适配不同的设备也是整套攻击方案中必不可少的部分。
值得一提的是,腾讯安全玄武实验室在研究实现过程时,对CPU“分支预测”功能的利用颇具有利用人工智能局限性的意味——通过五次训练让执行效果反馈为true,最终可以让CPU比较稳定的出现进入到分支内的推测逻辑。
“通过javascript想实现整套攻击需要解决很多问题”,宋凯最后总结道,包括如何稳定刷行缓存、确保特定的数据不出现在缓存中、高精度时间计时器、动态探测缓存大小。想要造成实际的危害,主要需要解决的问题是内存布局。
本次研究仅仅是腾讯安全玄武实验室部分的能力体现。在本次峰会上分享的宋凯曾代表腾讯安全玄武实验室赢得 Pwn2Own 2017 Edge 浏览器项目;曾连续三年入选微软 MSRC 全球 Top 100 贡献者榜单,最高排名第12位;更曾赢得2016年微软 Mitigation Bypass Bounty 项目,以及2015年和2016年的 Edge Bounty 项目。
实验室成员对于信息安全技术的深耕,也直接通过腾讯安全输出为技术能力,保卫广大用户的网络安全。在年初CPU漏洞爆发之后,除腾讯安全玄武实验室研发的在线检测工具之外,腾讯安全反病毒实验室和腾讯电脑管家也迅速上线相应的漏洞修复工具和检测工具,帮助用户快速方便的完成漏洞探测,及时发现隐患,将风险降到最低。
本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com
文章为作者独立观点不代本网立场,未经允许不得转载。