#php #encryption #mcrypt
#php #perl #url #кодирование #base64
Вопрос:
Рассматривая кодировку URL safe base 64, я обнаружил, что это очень нестандартная вещь. Несмотря на большое количество встроенных функций, которые есть в PHP, нет ни одной для URL-адреса в кодировке base 64. На странице руководства для base64_encode()
большинство комментариев предлагают использовать эту функцию, обернутую strtr()
:
function base64_url_encode($input)
{
return strtr(base64_encode($input), ' /=', '-_,');
}
Единственным модулем Perl, который я смог найти в этой области, является MIME::Base64::URLSafe (исходный код), который выполняет следующую замену внутри:
sub encode ($) {
my $data = encode_base64($_[0], '');
$data =~ tr| /=|-_|d;
return $data;
}
В отличие от функции PHP выше, эта версия Perl полностью удаляет символ ‘=’ (равно), а не заменяет его на ‘,’ (запятая), как это делает PHP. Equals — это символ заполнения, поэтому модуль Perl заменяет их по мере необходимости при декодировании, но это различие делает две реализации несовместимыми.
Наконец, функция Python urlsafe_b64encode (s) сохраняет заполнение ‘=’, побуждая кого-либо использовать эту функцию для удаления заполнения, которое заметно отображается в результатах Google для «URL-адрес python base64 безопасен»:
from base64 import urlsafe_b64encode, urlsafe_b64decode
def uri_b64encode(s):
return urlsafe_b64encode(s).strip('=')
def uri_b64decode(s):
return urlsafe_b64decode(s '=' * (4 - len(s) % 4))
Здесь желательно иметь строку, которая может быть включена в URL-адрес без дальнейшего кодирования, отсюда удаление или перевод символов ‘ ‘, ‘/’ и ‘=’. Поскольку определенного стандарта не существует, каков правильный способ?
Ответ №1:
Похоже, существует стандарт, это RFC 3548, раздел 4, кодировка Base 64 с безопасным алфавитом URL и имени файла:
Эта кодировка технически идентична предыдущей, за исключением символов алфавита 62:nd и 63:rd, как указано в таблице 2.
и /
следует заменить на - (minus)
и _ (understrike)
соответственно. Любые несовместимые библиотеки должны быть обернуты так, чтобы они соответствовали RFC 3548.
Обратите внимание, что для этого требуется, чтобы вы кодировали (pad) =
символы в URL, но я предпочитаю, чтобы URL кодировал символы
и /
из стандартного алфавита base64.
Ответ №2:
Я не думаю, что это правильно или неправильно. Но самая популярная кодировка
' /=' => '-_.'
Это широко используется Google, Yahoo (они называют это Y64). Самая безопасная для URL версия кодировщиков, которые я использовал на Java, Ruby поддерживает этот набор символов.
Комментарии:
1. 1 за упоминание Y64 и добавление некоторой культуры к вопросу
Ответ №3:
Я бы предложил запустить вывод base64_encode через urlencode. Например:
function base64_encode_url( $str )
{
return urlencode( base64_encode( $str ) );
}
Ответ №4:
Если вы спрашиваете о правильном способе, я бы выбрал правильную кодировку URL-адреса, а не произвольную замену символов. Сначала base64-закодируйте ваши данные, затем дополнительно закодируйте специальные символы, такие как «=», с правильной кодировкой URL (т. Е. %<code>
).
Комментарии:
1. Я не согласен с использованием уже доступных функций, но использование urlencode() может добавить много дополнительной длины.
Ответ №5:
Почему бы вам не попробовать обернуть его в urlencode()
? Документация здесь.
Комментарии:
1. Это использует ненужное количество символов. Почему бы просто не urlencode двоичную строку в первую очередь?