繁体   English   中英

在Javascript中,如何解码字符串中包含二进制(例如非UTF-8)数据的字符串?

[英]In Javascript, how do I decode a string in which decoded string contains binary (e.g. non UTF-8) data?

我有一个表示二进制数据的base64字符串(例如,在解码它或UTF-8数据后,它不是一个很好的可读字符串,否则此答案将对我有所帮助- 使用Javascript的atob解码base64不能正确地解码utf-8字符串 )。 我的JS是

var byteCharacters = atob(base64str);

导致

InvalidCharacterError: Failed to execute 'atob' on 'WorkerGlobalScope': The string to be decoded contains characters outside of the Latin1 range.

如何解码不是ASCII(甚至不是UTF-8数据)的基本64位字符串?

编辑:这是我正在谈论的字符串类型的示例。 使用Mac,我可以像这样对base64进行编码

openssl base64 -in ~/Downloads/star.jpg -out ~/Downloads/star.base64

这是生成的base64字符串。 如果您可以使用JS工具对此进行解码,那么您已经解决了问题。 通过执行“ cat myfile.base64”获得以下内容,因此希望“ cat”或我的剪切和粘贴操作不会在此处引入任何奇怪的字符。

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
AABJRU5ErkJggg==

最后编辑应从2015年相关 SO答案 中对此句子进行更多宣传

原始解决方案(已弃用)

当提到atob,btoa,base64js和其他库函数时:使用库节省时间并弃用atob和btoa

尝试将base64.js .toByteArray与您的数据一起使用。 跟随链接到Github自述库的链接:它说它完全可以实现您想要的,好吧,只有往返。

已在Chrome 66.0.3359.181上使用数据base64js.min.js成功测试@ 1.3.0

已使用Nodejs @ 4.4.7中的数据成功测试@ 1.3.0

自述文件中的引言:

base64js具有三个公开的函数,byteLength,toByteArray和fromByteArray,它们均采用单个参数。

  1. byteLength-接受base64字符串并返回字节数组的长度
  2. toByteArray-接受base64字符串并返回一个字节数组
  3. fromByteArray-获取字节数组并返回base64字符串

如果您可以访问原始二进制数据,我还将针对它应该/具有的任何文件类型/结构进行测试。

您是否首先针对base64测试了base64字符串,这是否是正确的base64字符串?

为了公平起见,当在客户端中作为脚本包含在Github存储库中的代码示例链接和更多信息时,请使用:

var byteArray = base64js.toByteArray(myBase64Str)

在Node中,您将执行以下操作:

var fs = require('fs')
var base64js =  require('base64-js')
fs.readFile('pathToMyBase64File', 'utf8', (err, data) => { // here 'utf8' is mandatory
  if (err) throw err;
  var byteArray = base64js.toByteArray(data)
  console.log(base64js.byteLength(data) == byteArray.length)
})

重要的是,myBase64File应该使用带有BOM的utf-8编码,否则将无法工作。

PS:我不是这个库的任何贡献者 ,只是一个让所有人都知道的好工具,MIT LICENSE MIT。

正如我在评论中已经提到的,问题在于编码。 您共享的base64字符串中包含许多换行符('\\ n')。 (通过cat )添加了换行符,以提高用户的可读性。 但是它们在解码时会造成麻烦。 如果在删除字符串中的所有'\\ n'之后尝试并尝试atob(),它应该可以正常工作。

获取没有空格或'\\ n'的base64字符串

在Linux中

$ base64 -w 0 ~/Downloads/star.jpg >~/Downloads/star.base64

在Mac中,您可以尝试openssl中的-A选项。

$ openssl base64 -A -in ~/Downloads/star.jpg -out ~/Downloads/star.base64

请使用结果字符串尝试atob()(直接从文件复制而不是从cat输出复制)。

注意:我不是Mac用户

如何解码不是ASCII(甚至不是UTF-8数据)的基本64位字符串?

你不能 Base64编码仅使用ASCII字符( AZaz0-9+/= )。 如果您的字符串包含非ASCII字符,则不是Base64数据。 这完全是另外一回事,而atob()对此无能为力。

最有可能的是字符串已经被解码了。

您可以尝试以下代码:

function decode_base64(s) {
  var b=l=0, r='',
  m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  s.split('').forEach(function (v) {
    b=(b<<6)+m.indexOf(v); l+=6;
    if (l>=8) r+=String.fromCharCode((b>>>(l-=8))&0xff);
  });
  return r;
}  

然后,您可以创建一个可以完成您的工作的异步函数:

function decode_base64_async(s, cb) {
  setTimeout(function () { cb(decode_base64(s)); }, 0);
}  

PS:我尚未检查此代码中是否包含非ASCII字符,因此您需要尝试一下

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM