Buffer.from(base64EncodedString, 'base64').toString('binary') 与 'utf8'

Buffer.from(base64EncodedString, 'base64').toString('binary') vs 'utf8'

提问人:Ryan 提问时间:2/11/2023 更新时间:2/14/2023 访问量:1192

问:

在 Node.js 中:为什么此测试在第二次调用时失败?main

test('base64Encode and back', () => {
  function main(input: string) {
    const base64string = base64Encode(input);
    const text = base64Decode(base64string);
    expect(input).toEqual(text);
  }

  main('demo');
  main('😉😉😉');
});

以下是我的功能:

export function base64Encode(text: string): string {
  const buffer = Buffer.from(text, 'binary');
  return buffer.toString('base64');
}

export function base64Decode(base64EncodedString: string): string {
  const buffer = Buffer.from(base64EncodedString, 'base64');
  return buffer.toString('binary');
}

从这些页面中,我认为我已经正确地编写了这些函数,以便一个函数可以反转另一个函数:

如果我将选项更改为改为,则测试通过。'binary''utf8'

但是我的数据库目前有数据,这个函数似乎只有在我使用 .'binary'

节点 .js 文本 编码 UTF-8 ASCII

评论

1赞 Matt 2/11/2023
节点中的字符串默认为 utf8。当 utf8 字符串转换为 latin1/binary 字符集时,它不能再表示😉多字节 utf8 字符。
0赞 Matt 2/11/2023
但问题可能还有更多,在 base64 之前/之后进行额外转换的目的是什么?与数据库中存储的内容有关的东西?
0赞 Ryan 2/13/2023
@Matt 你问的是 和 ?我需要一个而不是类型。Buffer.from(text, 'binary')buffer.toString('binary')stringBuffer
0赞 Matt 2/13/2023
是的,编码足以给你一个可移植的字符串。我只是在检查是否有特定原因使用该问题的答案,该答案将额外转换为 / ?base64latinbinary
0赞 Ryan 2/13/2023
@Matt 如果你把你的第一条评论写成答案,我会接受的。到目前为止,我还没有注意到任何使用问题(除了我的测试失败),所以也许我的数据还没有任何多字节字符。我想如果我确实需要支持表情符号等,我需要返回并解码数据库并使用 .谢谢。'binary''utf8'

答:

3赞 Matt 2/14/2023 #1

binarylatin1 的别名

'latin1':Latin-1 代表 ISO-8859-1。此字符编码仅支持 from to 的 Unicode 字符。每个字符都使用单个字节进行编码。不适合该范围的字符将被截断,并将映射到该范围内的字符。U+0000U+00FF

此字符集无法显示多字节 utf8 字符。

要取回 utf8 多字节字符,请直接转到并再次返回base64

function base64Encode(str) {
  return Buffer.from(str).toString('base64')
}
function base64Decode(str) {
  return Buffer.from(str, 'base64').toString()
}
> base64Encode('😉')
'8J+YiQ=='
> base64Decode('8J+YiQ==')
'😉'