【问题标题】:How atob doesn't convert from Buffer with base64?atob 如何不使用 base64 从 Buffer 转换?
【发布时间】:2020-07-31 23:12:57
【问题描述】:

我有使用lz-string 包加密的数据。

我还将结果转换为 base64 并使用atob() 函数从 base64 转换。

问题是atob() 没有按预期工作,但Buffer.from(b64, 'base64').toString(); 可以。

为什么?我该如何解决?我需要在客户端使用atob(浏览器中不存在缓冲区)。

StackBlitz example

【问题讨论】:

  • “没有按预期工作”是什么意思?
  • atob 应该从 base64 转换回来.. 但是当您运行我的示例时它不会这样做。至少没有正确的字符。
  • atob 确实从 base64 转换,我已经经常使用它,但它不会将输入解释为 UTF-8,这与 Buffer.toString() 不同。

标签: javascript node.js


【解决方案1】:

使用decodeURIComponentescape 转换为UTF-8。

const non64 = decodeURIComponent(escape(window.atob( b64 )));

【讨论】:

    【解决方案2】:

    如果您的 LZ 库支持,更有效(见下文)的选项是将 base64 编码的缓冲区解释为字符串并将其作为 Uint8Array 直接传递给库。你可以这样做

    const buffer = Uint8Array.from(atob(b64), c => c.charCodeAt(0))
    

    如果你真的需要一个字符串,你可以使用 TextDecoder,它比 Shlomi 公认的非常好的解决方案要少一些hacky:

    const text = new TextDecoder().decode(buffer)
    

    使用 TypedArray 更有效的原因有几个,并且 LZ 的实现应该真正适用于它们而不是字符串(并且可能使用 WebAssembly)。显然你跳过了 UTF-8 解码,但更重要的原因是因为在 JavaScript 中,字符串在内存中表示为 UTF-16,所以每个字符至少需要 2 个字节(在二进制字符串的情况下正好是 2 个字节),而Uint8Array——顾名思义——每个项目只使用一个字节。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-24
      • 2013-07-19
      • 2020-08-25
      • 1970-01-01
      • 2013-01-10
      • 2012-01-05
      • 1970-01-01
      • 2020-11-10
      相关资源
      最近更新 更多