Чому рядок, закодований base64, має в кінці знак =


321

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

Виникло кілька питань:

  1. Чи base64завжди рядок закінчується =?
  2. Чому додаток =додається в кінці?

9
Це абсолютно не стосується C #.
BoltClock

19
Насправді це стосується c #, не всі мови включатимуть =, наприклад, багато бібліотек perl опускають =, тому знання середовища, яким користувач користується, є релевантним.
Яків

Схоже, це робить його менш ефективним методом обфускування в деяких випадках, оскільки він досить помітний.
пт

6
@ user1167442 Base64 не для затуманення. Він призначений для транспортування двійкових даних (або рядків з unicode та іншими спеціальними символами) у вигляді рядка.
NH.

Відповіді:


269

Він служить в якості підкладки .

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


3
"Один випадок, коли потрібні додаткові символи - це об'єднання декількох файлів, кодованих Base64."
Андре Пуель

1
@ AndréPuel: пересинхронізації =вистачить. Якщо ви хочете знайти межі назад, то термінатор завжди повинен бути присутнім (і все одно потрібен лише один знак). Уся концепція прокладки Base64 - це просто розум…
6502

5
Однак це посилання абсолютно не має значення для base64.
NH.

1
Я просто бажаю, щоб було розміщено відповідне та надійне посилання, яке пояснює base64ефективність прокладки з ілюстраціями та прикладами. Нинішнє посилання на вікіпедію абсолютно не має значення, як @NH. згаданий.
Fr0zenFyr

1
@ Fr0zenFyr Якщо ви хочете посилання, en.wikipedia.org/wiki/Base64#Output_padding дуже добре. Але відповідь Бадра справді краща (вона просто ще не набрала голосів).
NH.

312

1-Ні

2- Як коротка відповідь: 65-й символ (знак "=") використовується лише як доповнення в остаточному процесі кодування повідомлення.

У вас не буде знаку '=', якщо ваша рядок має кратне число з 3 символів, оскільки Base64кодування займає кожні три байти (8 біт) і представляє їх як чотири символи для друку у стандарті ASCII.

Деталі:

(а) Якщо ви хочете кодувати

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

Base64буде мати справу (виробляючи 4 символи) з першим блоком і другим (у міру їх завершення), але для третього він додасть подвійний ==у висновку, щоб заповнити 4 потрібні символи. Отже , результат буде QUJD REVG Rw == (без місця)

(b) Якщо ви хочете кодувати ...

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

Аналогічно, він додасть лише одну =в кінці виводу, щоб отримати 4 символи, результатом буде QUJD REVG R0g = (без місця)


26
Це більш повна і зрозуміла, ніж інша відповідь і навіть Вікіпедія, і повинна заслуговувати більше голосів, ніж прийнята відповідь, яка не вказує лише на посилання на wikipedia. Кудо вам! Оголошено!
ANewGuyInTown

2
@ANewGuyInTown посилання на вікіпедію у прийнятому рішенні є невірним, воно не має нічого спільного з набиванням на base64. Правильну сторінку Legolas пов’язав у своїй відповіді нижче
Fr0zenFyr

Ще одна хороша відповідь (ІМХО) щодо відповіді про набивання base64
spottedmahn

66

З Вікіпедії :

Заключна послідовність '==' вказує, що остання група містила лише один байт, а '=' означає, що вона містила два байти.

Таким чином, це якась підкладка.


16
  1. Немає.
  2. Накладіть рядок, закодований Base64, до кратного довжиною 4 символи, щоб його можна було правильно розшифрувати.

3
Я видалив =кінець і перевірив це на 1 мільйон струн. Розшифровка завжди відповідала.
vivek_23

15

Її визначено в RFC 2045 як спеціальний символ прокладки, якщо в кінці кодованих даних є менше 24 біт.


11

Знак рівності (=) використовується як доповнення в певних формах кодування base64. У статті Вікіпедії на base64 є всі подробиці.


2
Чи можете ви пояснити логіку, чому "==" - 1 байт, а "=" - 2 байти? Я просто не можу це зрозуміти. Як прийти вхід: "будь-яке плотське задоволення". може отримати результат "YW55IGNhcm5hbCBwbGVhc3VyZS4 =", тоді як "будь-яке плотське задоволення" може отримати результат "YW55IGNhcm5hbCBwbGVhc3VyZQ =="?
null

14
Це не той випадок, що '==' - 1 байт, а '=' - 2 байти. Це справа, що вам потрібно завжди мати кратне 4 байти у всій рядку. Таким чином, ви прокладаєте знаки '=', поки цього не отримаєте. Перший рядок має ще один символ, ніж другий рядок, тому потрібна одна менша кількість '=' прокладки.
Сем Холлоуей

2
Чи повинна ця відповідь бути коментарем?
Fr0zenFyr

9

Це підкладка. З http://en.wikipedia.org/wiki/Base64 :

Теоретично символ розбивки не потрібен для розшифровки, оскільки кількість пропущених байтів може бути обчислена з числа цифр Base64. У деяких реалізаціях символ прокладки є обов'язковим, тоді як для інших він не використовується. Один випадок, коли потрібні додаткові символи - це об'єднання декількох закодованих файлів Base64.


1
Частина про "Один випадок, коли потрібні додаткові символи - це об'єднання декількох файлів, кодованих Base64". неправильно. Наприклад, при об'єднанні двох файлів base64, у яких вихідні байти для кожного файлу довжиною 3 байти, рядки base64 становитимуть 4 символи і не матимуть байтів. Коли ви з'єднаєте ці два рядки base64, не буде способу сказати, з чого починається, а одна зупиняється на основі солей на об'єднаному рядку. Тож покладатися на прокладку base64 допомогти у цьому не вийде. Цей випуск буде існувати для будь-якого файлу, довжина байтів якого рівномірно ділиться на 3.
Ron C

1
Я думаю, це означає той випадок, коли кінцевим результатом має бути конкатенація вхідних даних. наприклад, decode(encode(A)+encode(B))=A+Bпрацює з підкладкою, але не без цього.
Томас Леонард

можливо, але таке обмежене використання не дає змоги покладатися на символи прокладки для загального випадку розділення закодованих рядків, коли закодовані рядки з'єднані разом. Я згадую лише про те, щоб допомогти розробникам, які, можливо, думають, що вони можуть використовувати його таким чином.
Рон С

1
Я думаю, що ваше заперечення дійсно лише підкреслює різницю між поняттями прокладки та розмежування. Як правило, результати конкатенації не включають в себе достатньо інформації, щоб зробити її оборотною. Ви не знаєте, чи "c3dpenpsZXJz" спочатку був "c3dpenps" + "ZXJz" або "c3dp" + "enpsZXJz". Але ви також не знаєте, чи "swizzlers" спочатку був "swi" + "zzlers" або "swizzl" + "ers".
GargantuChet

1
Скопіюючи мій коментар із пов’язаної відповіді на підкладку Base64 :> Конкатенація Base64 [з '=' padding] дозволяє кодерам обробляти великі шматки паралельно без тягаря вирівнювання розмірів шматка до кратного трьох. Аналогічно, як деталь про реалізацію, там може бути кодер, якому потрібно промити внутрішній буфер даних розміром, який не кратний трьом.
Андре Д

7

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

Кодування "Марії було" до бази 64

У цьому прикладі ми використовуємо простий текстовий рядок ("Марія мала"), але принцип дотримується будь-яких даних (наприклад, графічний файл). Щоб перетворити кожні 24 біти вхідних даних у 32 біти вихідних даних, кодування Base 64 розбиває 24 біти на 4 фрагменти з 6 біт. Перша проблема, яку ми помічаємо, - це те, що "Марія мала" не кратне 3 байтам - вона становить 8 байт. Через це остання група бітів має лише 4 біти. Щоб виправити це, ми додаємо два додаткових біта "0" і запам'ятаємо цей факт, поставивши "=" в кінці. Якби текстовий рядок, який потрібно перетворити на Base 64, мав 7 байт, остання група мала б 2 біти. У цьому випадку ми додали б чотири зайвих біта "0" і запам'ятаємо цей факт, поставивши "==" в кінці.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.