Кодування двійкових даних у вигляді тексту
Кодування двійкових даних у вигляді тексту — це кодування даних у вигляді звичайного тексту. Точніше, це кодування двійкових даних у вигляді послідовності друкованих символів. Таке кодування необхідне для передачі даних, коли канал зв’язку не дозволяє передавати двійкові дані (наприклад, електронна пошта чи NNTP) або не є суто 8-бітовим. Документація PGP (RFC 4880) використовує на позначення кодування двійкових даних у вигляді тексту термін «броня ASCII», коли мова йде про Base64.
Основа потреби в кодуванні двійкового формату в текст виникає через потребу передавати довільні двійкові дані через наявні протоколи зв’язку, які були розроблені для передачі лише зрозумілого людям тексту англійською мовою. Ці протоколи зв’язку можуть бути безпечними лише на рівні 7 бітів (а отже, упускати частину керівних кодів ASCII), можуть вимагати розривів рядків з певною мінімальною частотою, і можуть не підтримувати пробіли. Таким чином, лише 94 друковані символи ASCII є "безпечними" для використання в передачі даних.
Стандарт кодування тексту ASCII використовує 7 бітів для кодування символів. Завдяки цьому можна закодувати 128 (тобто 27) унікальних значень (0–127) для представлення літер, цифр і знаків пунктуації, які зазвичай використовуються в англійській мові, а також набір керівних символів, які не є символами для друку. Наприклад, велика літера A представлена 7 бітами як 100 0001 2, 0x41 (101 8), цифра 2 — 011 0010 2 0x32 (62 8), символ } — 111 1101 2 0x7D (175 8), а керівний символ RETURN — це 000 11012 0x0D (158).
На противагу цьому, більшість комп’ютерів зберігають дані в пам’яті, організованій у восьмибітових байтах. Файли, які містять машинно-виконуваний код і нетекстові дані, зазвичай містять усі 256 можливих восьмибітових значень байтів. Чимало комп’ютерних програм покладаються на таку різницю між семибітовим текстом і восьмибітовими двійковими даними, і вони не працюватимуть належним чином, якщо символи, відмінні від ASCII, з’являться в даних, які, як очікується, міститимуть лише текст ASCII. Наприклад, якщо значення восьмого біта не зберігається, то програма може тлумачити значення байта понад 127 як позначку, що сповіщає її про виконання певної функції.
Проте нерідко бажано мати можливість надсилати нетекстові дані через текстові системи, наприклад, щоб можна було б прикріпити файл зображення до повідомлення електронної пошти. Для цього дані кодуються таким чином, що восьмирозрядні дані кодуються у вигляді семирозрядних символів ASCII (зазвичай з використанням лише буквоцифрових символів і знаків пунктуації — друкованих символів ASCII). Після безпечного прибуття до пункту призначення дані розкодовуються назад у свою восьмибітну форму. Цей процес називається кодуванням двійкових даних у вигляді тексту. Чимало програм виконують це перетворення, щоб забезпечити передачу даних, наприклад, PGP і GNU Privacy Guard .
Методи кодування двійкових даних у вигляді тексту також використовуються як механізм кодування простого тексту. Наприклад:
- Деякі системи мають більш обмежений набір символів, з якими вони можуть працювати; вони не тільки не є чисто 8-бітовими – деякі з них навіть не можуть обробляти частину друкованих символів ASCII.
- Інші системи мають обмеження на кількість символів, які можуть з’являтися між розривами рядків, як-от обмеження «1000 символів на рядок» у деяких програмах Simple Mail Transfer Protocol, як це дозволено RFC 2821.
- Треті додають до тексту заголовки чи прикінцеві метадані.
- Кілька протоколів, які вважаються поганими, але досі використовуються, користуються внутрішньосмуговою сигналізацією, що викликає плутанину, якщо в повідомленні зустрічаються певні патерни. Найвідомішим прикладом цього є рядок «From " (з пробілом на кінці) на початку рядка, який використовується для розділення поштових повідомлень у форматі файлів mbox.
Використовуючи кодування двійкових даних у вигляді тексту для повідомлень, які вже є простим текстом, а потім розкодовуючи їх з іншого боку передачі, можна зробити такі системи повністю прозорими. Це іноді називають «бронюванням ASCII». Наприклад, компонент ViewState ASP.NET використовує кодування base64 для безпечної передачі тексту через HTTP POST, щоб уникнути конфлікту розділювачів.
У наведеній нижче таблиці порівнюються найбільш поширені форми кодування двійкових даних у вигляді тексту. Вказана ефективність є співвідношенням між кількістю бітів на вході та кількістю бітів у закодованому виході.
Кодування | Тип даних | Ефективність | Реалізації на мовах програмування | Коментарі |
---|---|---|---|---|
Ascii85 | Довільний | 80% | awk [Архівовано 2014-12-29 у Wayback Machine.], C, C (2), C#, F#, Go, Java Perl, Python, Python (2) | Є декілька варіантів цього кодування – Base85, btoa тощо. |
Base32 | Arbitrary | 62.5% | ANSI C, Delphi, Go, Java, C# F#, Python | |
Base36 | Ціле число | ~64% | bash, C, C++, C#, Java, Perl, PHP, Python, Visual Basic, Swift, чимало інших | Використовує Арабські цифри від 0 до 9 та латинські літери від A до Z (базову латинську абетку ISO). Широко використовується системами перенаправлення URL, наприклад, TinyURL і SnipURL/Snipr, для компактних літерно-цифрових ідентифікаторів. |
Base45 | Довільний | ~67% (97%[a]) | Go, Python | Визначений у Специфікації IETF RFC 9285 для компактного додавання двійкових даних до QR-коду.[1] |
Base56 | Ціле число | — | PHP, Python, Go | Варіант кодування Base58, який ще більше уникає використання символів 'i' та 'o', щоб мінімізувати ризик шахрайства та людської помилки.[2] |
Base58 | Ціле число | ~73% | C++, Python, C#, Java | Подібний до Base64, але модифікований для уникання як нелітерно-цифрових символів (+ і /), так і літер, що можуть мати неоднозначний вигляд при друку (0 – нуль, I – велика i, O – велика o й l – мала L). Base58 використовується для представлення адрес біткойну. [джерело?] Частина систем спілкування та соціальних мереж додає розриви рядків у рядках, що не є літерно-цифровими. Цього уникли, не використовуючи символи, зарезервовані в URI, наприклад, +. У SegWit це кодування замінили Bech32, дивіться нижче. |
Base62 | Довільний | ~74% | Rust | Подібний до Base64, але містить лише літерно-цифрові символи. |
Base64 | Довільний | 75% | awk [Архівовано 2014-12-29 у Wayback Machine.], C, C (2), Delphi, Go, Python, чимало інших | Давнє та досі популярне кодування, вперше визначене як частина RFC 989 у 1987 році. |
Base85 (RFC 1924) | Довільний | 80% | C, Python, Python (2) | Переосмислена версія Ascii85. |
Base91[3] | Довільний | 81% | C# F# | Варіант зі сталою шириною |
basE91[4] | Довільний | 81% | C, Java, PHP, 8086 Assembly, AWK C#, F#, Rust | Варіант зі змінною шириною |
Base94[5] | Довільний | 82% | Python, C, Rust | |
Base122[6] | Довільний | 87.5% | JavaScript, Python, Java, Base125 Python і Javascript, Go, C | |
BaseXML[7] | Довільний | 83.5% | C Python JavaScript | |
Bech32 | Довільний | 62.5% + щонайменше 8 символів (позначка, розділювач, 6 символів ECC) | C, C++, JavaScript, Go, Python, Haskell, Ruby, Rust | Специфікація.[8] Використовується у Біткойні та Lightning Network.[9] Порція даних кодується як Base32 з можливістю перевірити та скоригувати до 6 хибних символів, завдяки 6 символам коду БЧХ у кінці, що також перевіряє та виправляє частину для людського прочитання. Варіант Bech32m має незначні зміни, завдяки яким він більш стійкий до змін довжини.[10] |
BinHex | Довільний | 75% | Perl, C, C (2) | MacOS Classic |
Десяткове | Ціле число | ~42% | Більшість мов | Зазвичай усталене представлення для введення чи виведення при взаємодії з людськими істотами. |
Шістнадцяткове (Base16) | Довільний | 50% | Більшість мов | Існує у варіантах з великими та малими літерами |
Intel HEX | Довільний | ≲50% | Бібліотека C, C++ | Здебільшого використовується для програмування мікросхем пам'яті EPROM і флешпам'яті типу NOR |
MIME | Довільний | Див. Quoted-printable і Base64 | Див. Quoted-printable і Base64 | Контейнер кодування для форматування, що нагадує форматування листів електронної пошти |
Відсоткове кодування | Текст (URI), Довільний (RFC1738) | ~40%[b] (33–70%[c]) | C, Python, можливо, чимало інших | |
Quoted-printable | Текст | ~33–100%[d] | Можливо, чимало | Зберігає розриви рядків; обрізає рядки після 76 символів |
S-record (шістнадцяткове Motorola) | Довільний | 49.6% | Бібліотека C, C++ | Здебільшого використовується для програмування мікросхем пам'яті EPROM і флешпам'яті типу NOR. Ефективність 49,6% обчислена виходячи з розміру запису 255 двійкових байтів. |
Tektronix hex | Довільний | Здебільшого використовується для програмування мікросхем пам'яті EPROM і флешпам'яті типу NOR. | ||
Uuencoding | Довільний | ~60% (до 70%) | Perl, C, Delphi, Java, Python, можливо, чимало інших | Давнє кодування, розроблене в 1980 році для Unix-to-Unix Copy. Здебільшого замінене MIME та yEnc |
Xxencoding | Довільний | ~75% (подібна до Uuencoding) | C, Delphi | Кодування, запропоноване (та подекуди використовується) як заміна для Uuencoding, щоб уникати проблем перекладу наборів символів між ASCII і системами EBCDIC, що можуть пошкоджувати дані, закодовані Uuencoding |
z85 (ZeroMQ spec:32/Z85) | Двійковий та ASCII | 80% (подібна до Ascii85/Base85) | C (оригінал), C#, Dart, Erlang, Go, Lua, Ruby, Rust та інші | Задає підмножину ASCII, подібно до Ascii85, пропускаючи кілька символів, що можуть призводити до вад програм (` \ " ' _ , ; ). Цей формат відповідає ZeroMQ spec:32/Z85.
|
RFC 1751 (S/KEY) | Довільний | 33% | C,[11] Python |
"Домовленість щодо 128-бітових ключів, доступних для прочитання людьми". Послідовність невеликих англійських слів людям легше читати, запам'ятовувати та друкувати, ніж десяткові числа чи інші системи кодування двійкових даних у вигляді тексту.[12] Кожне 64-бітове число відображене у вигляді шести коротких слів, кожне з яких має від одного до чотирьох символів, з публічного словника з 2048 слів.[11] |
Коди isprint 95 від 32 до 126 відомі як друковані символи ASCII.
Серед старіших та нині вже непоширених форматів – кодування BOO, BTOA та USR.
Більшість цих кодувань генерує текст, що містить лише підмножину всіх друкованих символів ASCII: наприклад, кодування base64 генерує текст, який містить лише великі та малі літери (A–Z, a–z), цифри (0–9), а також символи «+», «/» і «=».
Деякі з цих кодувань (quoted-printable і відсоткове кодування) базуються на наборі дозволених символів і одному символі екранування. Дозволені символи залишаються незмінними, тоді як усі інші символи перетворюються з додаванням перед ними символу екранування. Такий вид перетворення дає змогу отримати текст, який майже можна читати, оскільки серед дозволених символів є літери та цифри, тож вони залишаються такими, як вони є в закодованому тексті. Ці кодування створюють найкоротший звичайний вивід ASCII для введення, яке здебільшого складається з друкованих символів ASCII.
Деякі інші кодування (base64, uuencoding) засновані на відображенні всіх можливих послідовностей із шести бітів на різні друковані символи. Оскільки друкованих символів більше 26 = 64, це можливо. Дана послідовність байтів перекладається, розглядаючись як потік бітів, із розбиттям цього потоку на частини по шість бітів і генеруючи послідовність відповідних символів. Різні кодування відрізняються у відповідності між послідовностями бітів і символів, а також у тому, як форматується отриманий текст.
Деякі кодування (оригінальна версія BinHex і рекомендоване кодування для CipherSaber) використовують чотири біти замість шести, відображаючи всі можливі послідовності з 4 бітів на 16 стандартних шістнадцяткових цифр. Використання 4 бітів на кожен закодований символ дає на 50% довший вивід, ніж base64, але спрощує кодування та розкодування: розгортання кожного байта в джерелі, незалежно від двох закодованих байтів, простіше, ніж розгортання 3 вихідних байтів base64 до 4 закодованих байтів.
Серед перших 192 кодів PETSCII 164 мають видиме представлення, коли їх подати в лапках: 5 (білий), 17–20 і 28–31 (кольори та елементи керування курсором), 32–90 (еквівалент ASCII), 91–127 (графіка), 129 (помаранчевий), 133–140 (функціональні клавіші), 144–159 (кольори та елементи керування курсором) і 160–192 (графіка).[13] Це теоретично дозволяє кодування, наприклад base128, між машинами, що спілкуються на PETSCII.
- ↑ Кодування для генерації QR-коду автоматично вибирає кодування відповідно до вхідного набору символів, кодуючи 2 алфавітно-цифрові символи в 11 бітів, а Base45 кодує 16 бітів у 3 таких символи. Таким чином, ефективність становить 32 біти двійкових даних, закодованих в 33 біти: 97%.
- ↑ Для довільних даних; кодування кожного з 189 незарезервованих символів трьома байтами, а решти 66 символів - одним.
- ↑ Для тексту; кодування лише 18 зарезервованих символів.
- ↑ Один байт, що зберігається у вигляді =XX. Кодування всіх символів, крім 94 символів, які не потребують кодування (серед них пробіл і табуляція).
- ↑ Fältström, Patrik; Ljunggren, Freik; Gulik, Dirk-Willem van (11 серпня 2022). The Base45 Data Encoding.
Even in Byte mode, a typical QR code reader tries to interpret a byte sequence as text encoded in UTF-8 or ISO/IEC 8859-1. ... Such data has to be converted into an appropriate text before that text could be encoded as a QR code. ... Base45 ... offers a more compact QR code encoding.
- ↑ Duggan, Ross (18 серпня 2009). Base-56 Integer Encoding in PHP.
- ↑ Dake He; Yu Sun; Zhen Jia; Xiuying Yu; Wei Guo; Wei He; Chao Qi; Xianhui Lu. A Proposal of Substitute for Base85/64 – Base91 (PDF). International Institute of Informatics and Systemics.
- ↑ binary to ASCII text encoding. basE91. SourceForge. Процитовано 20 березня 2023.
- ↑ Convert binary data to a text with the lowest overhead. Vorakl's notes. 18 квітня 2020.
- ↑ Albertson, Kevin (26 листопада 2016). Base-122 Encoding.
- ↑ BaseXML - for XML1.0+. GitHub. 16 березня 2019.
- ↑ bitcoin/bips. GitHub. 8 грудня 2021.
- ↑ Rusty Russell та ін. (15 жовтня 2020). Payment encoding in the Lightning RFC repo. GitHub.
- ↑ Bech32m format for v1+ witness addresses. GitHub. 5 грудня 2021.
- ↑ а б RFC 1760 "The S/KEY One-Time Password System".
- ↑ RFC 1751 "A Convention for Human-Readable 128-bit Keys"
- ↑ http://sta.c64.org/cbm64pet.html et al