Почему строка в кодировке base64 имеет знак = в конце

322

Я знаю, что такое base64кодировка и как рассчитать base64кодировку в C #, однако я несколько раз видел, что когда я конвертирую строку в base64, =в конце есть.

Возникло несколько вопросов:

  1. Всегда ли base64строка заканчивается =?
  2. Почему =добавляется в конце?
Сантош Сингх
источник
9
Это не имеет абсолютно никакого отношения к C #.
BoltClock
19
На самом деле это связано с c #, не все языки будут содержать =, например, многие библиотеки perl опускают =, поэтому знание среды, которую использует пользователь, действительно актуально.
Джейкоб
Похоже, что в некоторых случаях это делает его менее эффективным методом запутывания, поскольку его можно обнаружить.
КГВР
6
@ user1167442 Base64 не для запутывания. Он предназначен для передачи двоичных данных (или строк с юникодом и другими специальными символами) в виде строки.
НХ.

Ответы:

270

Это служит дополнением .

Более полный ответ заключается в том, что строка, закодированная в base64, не всегда оканчивается на a =, она будет оканчиваться на один или два, =если они требуются для заполнения строки до нужной длины.

Эндрю Хэйр
источник
3
«Одним из случаев, когда требуются дополнительные символы, является объединение нескольких файлов в кодировке Base64».
Андре Пуэль
1
@ AndréPuel: повторной синхронизации =будет достаточно. Если вы хотите найти границы назад, всегда должен присутствовать терминатор (и все же нужен только один символ). Вся концепция дополнения Base64 - просто мозговая мысль ...
6502
5
Эта ссылка совершенно не имеет отношения к base64.
НХ.
1
Я просто хочу, чтобы была опубликована соответствующая и надежная ссылка, которая объясняет base64эффективность заполнения с иллюстрациями и примерами. Нынешняя ссылка на википедию абсолютно не имеет отношения к @NH. упоминается.
Fr0zenFyr
1
@ Fr0zenFyr Если вам нужна ссылка, en.wikipedia.org/wiki/Base64#Output_padding довольно хорош. Но ответ Бадра действительно лучше (он просто еще не набрал голоса).
НХ.
313

1-Нет

2- В качестве краткого ответа: 65-й символ (знак "=") используется только в качестве дополнения в конечном процессе кодирования сообщения.

У вас не будет знака «=», если ваша строка имеет кратное число из 3 символов, потому что Base64кодирование занимает каждые три байта (8 бит) и представляет их как четыре печатных символа в стандарте ASCII.

Подробности :

(а) Если вы хотите кодировать

ABCDEFG <=> [ ABC] [ DEF] [G

Base64будет иметь дело (производя 4 символа) с первым блоком и вторым (так как они завершены), но для третьего он добавит двойное число ==в вывод, чтобы завершить 4 необходимых символа. Таким образом , результатом будет QUJD REVG Rw == (без пробела)

(б) Если вы хотите кодировать ...

ABCDEFGH <=> [ ABC] [ DEF] [GH

Точно так же это добавит только один =в конце вывода, чтобы получить 4 символа, результат будет QUJD REVG R0g = (без пробела)

Бадр Беллай
источник
26
Это более полный и ясный ответ, чем другой ответ и даже Википедия, и должен заслуживать большего количества голосов, чем принятый ответ, который лишь указывает на ссылку в Википедии. Слава тебе! Upvoted!
ANewGuyInTown
2
@ANewGuyInTown ссылка на википедию в принятом решении неверна, она не имеет ничего общего с заполнением на base64. Правильная страница была связана с Леголасом в его ответе ниже
Fr0zenFyr
Еще один хороший (ИМХО) связанный ответ о заполнении base64
spottedmahn
66

Из Википедии :

Последняя последовательность '==' указывает, что последняя группа содержала только один байт, а '=' указывает, что она содержала два байта.

Таким образом, это какой-то отступ.

Леголас
источник
16
  1. Нет.
  2. Строка в кодировке Base64 должна быть кратна длине 4 символов, чтобы ее можно было правильно декодировать.
Ян Кемп
источник
3
Я удалил =в конце и проверил это на 1 миллион строк. Декодирование всегда совпадает.
vivek_23
15

Он определен в RFC 2045 как специальный символ заполнения, если в конце закодированных данных доступно менее 24 бит.

iandotkelly
источник
11

Знак равенства (=) используется в качестве заполнения в определенных формах кодирования base64. Статья Википедии на base64 имеет все детали.

Сэм Холлоуэй
источник
2
Не могли бы вы объяснить логику того, почему "==" равен 1 байту, а "=" - 2 байта? Я просто не могу этого понять. Как получилось высказывание: «Любое плотское удовольствие». мог получить результат "YW55IGNhcm5hbCBwbGVhc3VyZS4 =", в то время как "любое плотское удовольствие" мог получить результат "YW55IGNhcm5hbCBwbGVhc3VyZQ =="?
ноль
14
Это не тот случай, когда '==' равен 1 байту, а '=' равен 2 байта. Это тот случай, когда вам нужно всегда иметь кратное 4 байта во всей вашей строке. Таким образом, вы дополняете знаками «=», пока не получите это. Первая строка имеет на один символ больше, чем вторая строка, поэтому требуется меньше '=' отступа.
Сэм Холлоуэй
2
Этот ответ должен быть комментарием?
Fr0zenFyr
9

Это набивка. С http://en.wikipedia.org/wiki/Base64 :

Теоретически, символ дополнения не требуется для декодирования, так как количество пропущенных байтов может быть вычислено из числа цифр Base64. В некоторых реализациях символ заполнения является обязательным, в то время как для других он не используется. Одним из случаев, когда требуются дополнительные символы, является объединение нескольких файлов в кодировке Base64.

Томас Леонард
источник
1
Часть о «Один случай, в котором требуются символы заполнения, - это конкатенация нескольких файлов в кодировке Base64». неправильно. Например, при объединении двух файлов base64, где исходные байты для каждого файла имеют длину 3 байта, строки base64 будут иметь длину 4 символа и не будут содержать байтов заполнения. Когда вы объединяете эти две строки base64, вы не сможете определить, где начинается одна, а какая останавливается, основываясь только на объединенной строке. Поэтому полагаться на заполнение base64, чтобы помочь с этим, не сработает. Эта проблема будет существовать для любого файла с длиной в байтах, равномерно делимой на 3.
Рон С
1
Я предполагаю, что это означает случай, когда конечным результатом должна быть конкатенация входных данных. например, decode(encode(A)+encode(B))=A+Bработает с отступами, но не без.
Томас Леонард
возможно, но такое ограниченное использование не позволяет полагаться на дополнительные символы в общем случае разделения кодированных строк, когда кодированные строки объединяются вместе. Я упоминаю это только для того, чтобы помочь разработчикам, которые думают, что могут использовать его таким образом.
Рон С
1
Я думаю, что ваше возражение на самом деле просто подчеркивает разницу между понятиями заполнения и разграничения. Результаты конкатенации обычно не содержат достаточного количества информации, чтобы сделать ее обратимой. Вы не будете знать, было ли изначально "c3dpenpsZXJz" "c3dpenps" + "ZXJz" или "c3dp" + "enpsZXJz". Но вы также не знаете, были ли «swizzlers» изначально «swi» + «zzlers» или «swizzl» + «ers».
GargantuChet
1
Копирование моего комментария из связанного ответа с заполнением Base64 :> Конкатенация Base64 [с заполнением '='] позволяет кодировщикам обрабатывать большие фрагменты параллельно без необходимости выравнивания размеров фрагментов, кратных трем. Точно так же, как деталь реализации, может существовать кодер, который должен очищать внутренний буфер данных размером, не кратным трем.
Андре Д
7

http://www.hcidata.info/base64.htm

Кодировка "Мария была" для Base 64

В этом примере мы используем простую текстовую строку («Мэри имела»), но принцип действует независимо от того, что это за данные (например, графический файл). Чтобы преобразовать каждые 24 бита входных данных в 32 бита вывода, кодирование Base 64 разбивает 24 бита на 4 порции по 6 бит. Первая проблема, которую мы замечаем, состоит в том, что "Mary" не является кратным 3 байтам - это 8 байтов в длину. Из-за этого последняя группа битов имеет длину всего 4 бита. Чтобы исправить это, мы добавляем два дополнительных бита «0» и запоминаем этот факт, ставя «=» в конце. Если бы текстовая строка для преобразования в Base 64 имела длину 7 байт, последняя группа имела бы 2 бита. В этом случае мы добавили бы четыре дополнительных бита «0» и запомнили бы этот факт, поставив «==» в конце.

Dev
источник