Нужно ли вручную удалять заполнение = из строки в кодировке Base64Url в Dart?
Я с удивлением заметил, что когда я преобразовал строку в Base64Url в Dart, я получил строку, которая заканчивается =
символ заполнения.
import 'dart:convert';
main() {
String credentials = "username:password";
String encoded = base64Url.encode(utf8.encode(credentials));
print(encoded); // dXNlcm5hbWU6cGFzc3dvcmQ=
}
Я думал, что целью Base64Url является удаление символов, которые не будут хорошими в URL. Очевидно нет. Документы даже есть в списке. Значит ли это, что я должен удалить его вручную?
final noPadding = encoded.replaceAll(RegExp('='), ''); // dXNlcm5hbWU6cGFzc3dvcmQ
1 ответ
Спецификация для base64url
(URL и имя файла безопасны) заменяет только 62-й (+
) и 63 (/
) персонажи нормальные base64
с -
а также _
соответственно. Не заменяет символ заполнения (=
), но вместо этого делает это заявление:
Символ заполнения "=" обычно кодируется в процентах при использовании в URI, но если длина данных известна неявно, этого можно избежать, пропустив заполнение.
Хотя можно удалить заполнение, вы должны быть осторожны, потому что это не обрабатывается автоматически, и метод декодирования выдаст ошибку, если вы не уверены, что сначала восстановите заполнение, используя что-то вроде normalize()
,
Вместо этого я бы рекомендовал просто использовать процентное кодирование, которое доступно в Uri
class, так как реализация Dart base64 уже автоматически поддерживает строки в процентах:
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 имеет смысл использовать процентное кодирование в любом случае, потому что это ожидаемое поведение в URL и сохраняет всю строку, поэтому ее не нужно нормализовать позже.