我是否需要从 Dart 中的 Base64Url 编码字符串中手动删除 = 填充?

Do I need to manually remove the = padding from a Base64Url encoded string in Dart?

我惊讶地发现,当我在 Dart 中将一个字符串转换为 Base64Url 时,我得到一个以 = 填充字符结尾的字符串。

import 'dart:convert';

main() {
  String credentials = "username:password";
  String encoded = base64Url.encode(utf8.encode(credentials)); 

  print(encoded);  // dXNlcm5hbWU6cGFzc3dvcmQ=
}

我认为Base64Url 的意义在于去除URL 中不好的字符。显然不是。 docs 甚至列出了它。那么这是否意味着我必须自己手动删除它?

final noPadding = encoded.replaceAll(RegExp('='), ''); // dXNlcm5hbWU6cGFzc3dvcmQ

base64urlspec(URL 和文件名安全)仅替换正常的第 62 个(+)和第 63 个(/)字符base64-_ 分别。它不替换填充字符 (=),而是声明:

The pad character "=" is typically percent-encoded when used in an URI, but if the data length is known implicitly, this can be avoided by skipping the padding.

虽然可以删除填充,但您必须小心,因为它不会自动处理,如果您不确保首先使用类似 normalize().

我建议只使用 Uri class 中可用的百分比编码,因为 Dart base64 实现已经自动支持 percent-encoded 字符串:

import 'dart:convert';

main() {
  String input = 'username:password';
  String encoded = Uri.encodeComponent(base64Url.encode(utf8.encode(input)));
  print(encoded); // dXNlcm5hbWU6cGFzc3dvcmQ%3D
  String decoded = utf8.decode(base64Url.decode(encoded));
  print(decoded); // username:password
}

此外,如果您将 base64url 编码的字符串作为 URL 的一部分传递,则无论如何使用 percent-encoding 都是有意义的,因为这是 [=36= 中的预期行为] 并保留整个字符串,因此以后不必对其进行规范化。