Симметрии нет, потому что Base64 не является взаимно-однозначным отображением для дополненных строк. Давайте начнем с фактического декодированного контента. Если вы просматриваете свою расшифрованную строку в шестнадцатеричном формате (например, s.unpack('H*')
, это будет так:
6B C7 67 | B2 38 3C | 6A 2C 3C | 8E
Я добавил границы для каждого входного блока в алгоритм Base64: он принимает 3 октета ввода и возвращает 4 символа вывода. Таким образом, наш последний блок содержит только один входной октет, поэтому результатом будет 4 символа, которые заканчиваются на "==" в соответствии со стандартом.
Посмотрим, какой будет каноническая кодировка этого последнего блока. В двоичном представлении 8E
равно 10001110
. RFC говорит нам заполнить недостающие биты нулями, пока мы не достигнем требуемых 24 битов:
100011 100000 000000 000000
Я сделал группы из 6 битов, потому что это то, что нам нужно, чтобы получить соответствующие символы из алфавита Base64. Первая группа (100011) переводится в десятичное число 35 и, таким образом, представляет собой j
в алфавите Base64. Второе (100000) - это 32 знака после запятой и, следовательно, 'g' Два оставшихся символа должны быть дополнены как "==" в соответствии с правилами. Таким образом, каноническая кодировка
jg==
Если вы посмотрите на jq == сейчас, в двоичном виде это будет
100011 101010 000000 000000
Так что разница во второй группе. Но так как мы уже знаем, что нам интересны только первые 8 бит («==» говорит нам об этом -> мы получим только один декодированный октет из этих четырех символов), мы на самом деле заботимся только о первых двух битах вторая группа, потому что 6 битов группы 1 и 2 первых бита группы 2 образуют наш декодированный октет. 100011 10
вместе образуют наше начальное 8E
значение байта. Остальные 16 бит не имеют к нам отношения и поэтому могут быть отброшены.
Это также означает, что понятие «строгого» кодирования Base64 имеет смысл: нестрогое декодирование отбрасывает весь мусор в конце, тогда как строгое декодирование проверяет, чтобы оставшиеся биты были равны нулю в последней группе из 6. Вот почему ваше неканоническое кодирование будет отклонено строгими правилами декодирования.