У цій статті ми поговоримо про те, як кодується текст у сучасних комп'ютерах, а також про такі поняття, як Unicode, UTF-8 та ASCII (І не тільки).
Це запис слідами відеоуроку, який можна знайти на YouTube:
Цей запис також доступний у каналі Telegram “DEV: Рубінові тони”, а обговорити цю тему можна в нашому чаті Telegram. Статтю написано з використанням керівництва Джоеля Спольського.
Навіщо потрібні кодування?
Люди говорять, думають і пишуть природними мовами, багато з яких розвивалися протягом століть. Звичайно, і у світі IT ми хотіли б працювати з текстовою інформацією у звичному вигляді, але проблема полягає в тому, що сучасні комп'ютери розуміють лише нулики та одиниці: так – ні, правда – брехня, є сигнал – немає сигналу. Втім, часто й людям теж простіше мислити категоріями "погано – добре", а не розумітися на "градаціях сірого" якогось явища (про те, до чого це іноді призводить, я тут міркувати не буду). Так чи інакше, наші тексти потрібно якимось чином зберігати у цифровому вигляді, і сьогодні ми спробуємо зрозуміти які для цього використовуються підходи.
Розбиратися у всьому цьому справді корисно, тому що різних мов у світі дуже багато, питання інтернаціоналізації (про те, що це таке, я писав в іншій статті) та локалізації дуже актуальне.
Стандарт ASCII
Як працює ASCII?
Перенесемося в стародавні часи, на сорок років тому, коли була написана перша версія книги про мову C, а світ взагалі був простіше, трава зеленіша, та й пиво не розбавляли. Основну увагу тоді приділяли звичайним латинським символам без усяких вишукувань, тобто без умляутів та іншого.Для них використовувався стандарт кодування ASCII (American Standard Code for Information Interchange), який спочатку з'явився ще у 60-якомусь бородатому році.
Суть цього стандарту проста: кожну букву можна закодувати якимось цілим невід'ємним числом, наприклад “A” – це 65, “B” – 66, тощо. Це можна перевірити і зараз, наприклад написавши "A".ord в Ruby (хоча тут є особливість, про це пізніше). До речі, зауважимо, що тип char в C — це просто ціле число. Так ось, кожна буква латинського алфавіту і деякі інші символи типу знаків оклику / запитань, математичних операторів та іншого, кодувалися числами від 32 до 127. Це, ясна річ, чудово влазило в сім біт. Ну, а оскільки комп'ютери оперували і вісьмома бітами без жодних проблем, то залишався ще цілий вільний біт, за допомогою якого можна було втілити в життя найпотаємніші фантазії.
Коди від 0 до 31 включно використовувалися для будь-яких темних справ і називалися “контрольні символи” (aka “недруковані”). Наприклад, один із символів міг змусити комп'ютер пищати в самому прямому сенсі, інший означав табуляцію, і так далі (про \n, \t та інші штуки, думаю, всі знають). Знайти список усіх кодів можна в Інтернеті.
Використання ASCII для різних алфавітів
Загалом все працювало чудово, але тільки для тих, хто використовував англійську мову. Звичайно, багатьом спала на думку проста думка: "Раз коди від 128 до 255 ні для чого не використовуються, то їх можна задіяти під будь-що!". На жаль, поняття "що завгодно" у всіх різне. Так, в IBM-PC ці коди виводили на екран всякі рисочки, загогуліни та символи квадратного кореня (ось тут весь набір).В інших системах ситуація могла бути зовсім інший, і це часто призводило до всяких неприємностей. Наприклад, якщо на деяких комп'ютерах код 130 виводив é, то на комп'ютерах, що продаються в Ізраїлі, це число кодувало букву гімель ג. Виходило, що документ, складений у США і відправлений до Ізраїлю, міг неправильно виводитися на тамтешніх комп'ютерах (згадаймо про таке слово, як “résumé”).
З кириличними символами також була ціла історія. На зльоті СРСР було прийнято ГОСТ, який вводив кодування КОІ8, сумісну з ASCII, а вигадав її метр Чернов, який, на жаль, помер кілька років тому. КОИ8 задіяла "зайві" коди з 128-го. Були різновиди цього кодування, наприклад, KOI8-RU, призначений одразу для російської, української та білоруської мов.
Стандарт ANSI
У результаті весь цей хаос із “зайвими” кодами було вирішено хоч трохи впорядкувати. Так з'явився стандарт ANSI (American National Standards Institute), Що чітко зафіксував, що означають коди з 0 по 127, хоча, чесно кажучи, це і так в основному дотримувалося. А ось з кодами від 128 і далі надійшли цікаво, ввівши таку штуку, як кодові сторінки (cp, кодові сторінки). У таких сторінках зашивалися як звичайні латинські символи, і “нестандартні” літери алфавіту тієї країни, де ви. Тому на території колишнього СРСР багато хто любив кодування "windows cp 1251" саме тому, що 1251 – це номер відповідної сторінки з кириличними символами. В Ізраїлі для івриту використовувалася сторінка 1255, у Греції — 1253, і так далі таких таблиць було вище даху. Деякі сторінки могли використовуватися відразу для кількох мов, але це скоріше виняток.
Проблема з таким новаторським підходом у тому, що одночасно можна використовувати лише одну сторінку, тобто працювати по-людськи відразу, наприклад, з російською мовою та івритом на одному комп'ютері було нереально. Ну, хіба що писати власну програму та відображати деякі символи у якомусь хитрому вигляді.
В Азії ж взагалі панував треш і чад, тому що в тамтешніх країнах використовуються різноманітні ієрогліфи і всякі складні закарючки, яких існує близько 9000 — ясна річ, що в 8 біт це ніяк не вмістити. Доводилося йти на будь-які хитрощі і зберігати деякі символи у вигляді одного байта, а деякі – у вигляді двох, що дуже ускладнювало роботу з рядками (наприклад, не цілком зрозуміло, як рухатися в рядку назад). Так, звичайно, для всього цього існували допоміжні функції, але в цілому ситуація була така собі. Тим більше, що активно розвивався інтернет, тексти передавалися з комп'ютера на комп'ютер, і треба було цей бардак якось розгрібати.
Стандарт Unicode
Тоді з'явився Unicode, стандарт, мета якого була ввести єдине кодування для всіх алфавітів, які використовуються на планеті (ніяких клінгонських мов там спочатку, мабуть, не планувалося, але в цілому можна додати їх також).
Підхід Unicode суттєво відрізнявся від того, що було раніше. Як ми вже з'ясували, в ASCII ситуація проста: є буква "A" латинського алфавіту і є її уявлення у вигляді бітів 0100 0001 все просто. У Unicode ж букві зіставляється code point (кодова точка), що у свою чергу має певне уявлення у пам'яті чи диску, і це уявлення чітко не регламентовано.
Літери та їх зовнішній вигляд
Перш ніж рухатися далі, є один важливий момент, який слід усвідомити.Ми розуміємо, що латинська літера "A" – це не те саме, що латинська "B". Відрізняється вона і від малої літери "a", так? Але при цьому латинська "А", написана курсивом або напівжирним шрифтом, – це те саме, що просто латинська "A". Більше того, "А", написана шрифтом Arial, нічим із змісту не відрізняється від "А", написаної Helvetica. Чи означає це, що будь-які "прикраси" не важливі і їх можна не позначати? Взагалі, ні.
Думаю, багато хто знає, що у німецькій мові є символ ß. І це зовсім не "гарна літера B", а дві літери "s". У латиській мові є буква ķ, але це зовсім не звичайна латинська “k” з рисою для краси, а окрема буква. Тому "кіт" буде саме "kaķis" ("катіс", а не те, що ви подумали). Більше того, в івриті здавалося б одна й та сама буква, написана в різних місцях та в різному “стилі”, може мати різне значення. Значить, інформацію про "краси" теж потрібно зберігати!
Загалом, ситуація з мовами та алфавітами значно складніше, ніж здається. Саме тому робоча група Unicode витратила цілу купу часу на пошуки рішення, тим більше, що тут є політичні моменти, але нас це мало цікавить.
Принцип роботи Unicode
Суть цього стандарту така. Кожній "звичайній букві без особливих надмірностей", тобто звичайним "A", "B", і так далі, були присвоєні спеціальні "магічні числа", що записуються у вигляді U +1234. Це магічне число — кодова точка, U — ясна річ, Unicode, а самі цифри — шістнадцяткові. Всі ці кодові точки можна знайти на сайті Unicode, наприклад, U+00BF — це такий перевернутий питання, що використовується в іспанській мові.
Правда, дещо складніше, тому що Unicode дозволяє модифікувати символи та отримувати нові комбінації. Тобто до “просто букв” можна додавати комбіновані діакритичні знаки та акценти (типовий приклад – знак наголосу). Хоча для багатьох комбінацій вже є готові коди, можна збирати нові символи самостійно. Грубо кажучи, якщо взяти букву "е" і приліпити до неї дві точки, вийде "е". Ну, а букву “é” можна представити як U+0065 (звичайна латинська “e”) та U+0301 (акцент, що застосовується до попередньої букви). В принципі, це означає, що з будь-якої “нормальної” літери можна отримати дивного монстра Франкенштейна.
За фактом, жодної строгої межі на кількість символів в Unicode немає, хоча деяка частина влазить у розмірність 2 байти (тобто 65 536 штук). Взагалі, валідних кодових точок Unicode зараз близько 1112064, тому історія про те, що Unicode оперує тільки двома байтами – міф.
Кодування UTF-16
Інше цікаве питання полягає в тому, як ці кодові точки повинні бути представлені в пам'яті або в повідомленнях (у тих же електронних листах), оскільки сам стандарт це не регламентує. Для цього використовуються кодування.
Перша ідея була дуже простою — давайте зберігати ці шістнадцяткові числа у двобайтовому вигляді! Тоді рядок “Hello” буде представлений як U+0048 U+0065 U+006C U+006C U+006F, а в пам'яті – просто як 00 48 00 65 00 6C 00 6C 00 6F. Називається такий підхід UCS-2 (бо байта два, повідомляє cpt. Obvious) або UTF-16 (так-так, тому що 16 біт). Власне, звідси й пішов міф, що в Unicode може бути лише два байти, не більше. Тобто байта два, але тільки в конкретному кодуванні, що реалізує стандарт.
Але, з іншого боку, рядок "Hello" можна написати і в іншому вигляді, переставивши байти місцями: 48 00 65 00 6C 00 6C 00 6F 00 . Іншими словами, можна використовувати варіант little-endian або big-endian — тут уже в залежності від того, з чим зручніше працюватиме процесору. Виходить, форм зберігання вже принаймні дві! Як їх розрізняти? Тоді було запропоновано на початок кожного рядка додавати таку штуку як Unicode Byte Order Mark (тобто мітку, що повідомляє про порядок проходження байтів). Вона виглядала як FE FF або FF FE (у другому випадку це означає, що байти потрібно переставити місцями).
Потім очікувано запитали й інше питання: а чого нам зберігати всі ці зайві нулі? Це особливо актуально для англомовних розробників, які використовували в основному коди до U+00FF . З їхньої точки зору виходило, що для зберігання рядків доводиться витрачати вдвічі більше місця незрозуміло навіщо. Це не кажучи про те, що з часів дідуся залишилася гора документів в ANSI і ще бог знає в чому, і нікому не хотілося це все конвертувати. Коротше, до якогось моменту Unicode не набував поширення, але годинники оглушливо цокали, і ситуація ставала гіршою.
Кодування UTF-8
Тоді в 2003 році придумали концепцію UTF-8, яку пропонувалося використовувати для зберігання рядків Unicode (тобто Unicode != UTF8). Як підказує цифра 8, автори запропонували зберігати дані в октетах (байтах), але їх кількість варіюється в залежності від кодової точки. Іншими словами, від U+0000 до U+007F (від 0 до 127) використовується лише один байт, від U+0080 до U+07FF – два байти, і таке інше. Максимум – 4 байти інформації, що дозволяє закодувати весь мільйон з хвостиком кодових точок, що є на даний момент.
Це дуже зручно для документів у кодуванні US-ASCII (United States), в яких використовуються символи до U+007F, тобто кожен символ кодується одним байтом. З цього випливає, що такі документи виглядають однаково, що в ASCII, що в Unicode, тобто 65 – це "А" в обох випадках. Тому насправді "A".ord у Ruby поверне код літери для UTF8 ("A".encoding майже напевно повідомить саме UTF8, у всякому разі, на будь-якій нормальній системі).
Так, невелика проблема полягає в тому, що решті світу все одно довелося підлаштовуватися під новий стандарт, але що вдієш, ka ir tas ir. Заради справедливості, англійська — мова міжнародного спілкування плюс програми теж пишуться латинськими літерами.
Таким чином, з'явилося вже два кодування: UTF16 та UTF8. Тільки в одній кожен символ займав по 2 байти і треба було розбиратися, в якій послідовності ці байти записані, а в іншій багато "звичні" літери займали всього байт. Нескладно здогадатися, яке кодування набуло великої популярності.
Unicode та його численні кодування
До речі, це єдині варіанти. Був такий звір як UTF7, схожий на UTF8, але який гарантував, що старший біт завжди міститиме нуль. Це було зроблено, щоб текстові повідомлення, надіслані через деякі дивні поштові системи, доходили по-нормальному (інакше там могло бути таке, що частина інформації обрізалася). Був і UCS4 (за фактом, UTF32), який зберігав дані по 4 байти, але це здавалося занадто великим марнотратством.
Власне, тепер ми розуміємо, що всяких кодувань справді вигадали неабияку кількість.Звідси ростуть ноги у таємничих знаків запитання, які можна періодично зустріти в деяких випадках – це символи, які в даному кодуванні не вдається відобразити. Грубо кажучи, можна взяти будь-яку кодову точку з Unicode і спробувати відобразити в ASCII, але далеко не для всіх чисел вдасться знайти відповідність, що призведе до появи веселих знаків запитання.
Кодування потрібно шанувати
З усього цього виходить цікавий висновок: рядок фактично не матиме жодного сенсу, якщо ми не знаємо, яке кодування воно використовує. Хоча ми все одно використовуємо термін "plain text", він виявляється досить розмитим, тому що неясно в якомусь кодуванні він "plain". Якщо у ньому використовуються будь-які символи після 127, то ASCII тут теж допоможе. Саме тому при створенні веб-сторінок у тезі meta ми пишемо кодування (а якщо не пишемо, то варто було б це робити) – аналогічна історія з листами.
До речі, із веб-сторінками взагалі дуже цікава штука. Спочатку планувалося, що кодування повідомлятиме веб-сервер при відправці HTML. Але ж на одному сервері може лежати величезна кількість сторінок і сайтів, що використовують різні мови. Значить, краще, щоб сама веб-сторінка говорила, що вона має за кодування. Але, дозвольте, як тоді нам цю сторінку почати читати, якщо ми не маємо уявлення про її кодування? Виходить замкнуте коло: щоб прочитати сторінку, потрібно знати кодування, а щоб знати кодування, потрібно почати читати сторінку.
На щастя, на початку HTML-файлу ми зазвичай використовуємо “стандартні” коди до 127, а meta розташовується на самому початку документа, так що її можна обробити без проблем, а потім вже використовувати зазначене кодування.Якщо ж meta немає, то деякі браузери можуть намагатися "вгадати" кодування за допомогою аналізу "нестандартних" символів, але іноді це може призвести до того, що замість кириличних символів вилізуть якісь китайські ієрогліфи. Тому, пані та панове, ми з вами повинні шанувати кодування.
ASCII – таблиця кодування символів, де кожному числу, знаку, літері відповідає певне число. У ній міститься 128 символів, які пронумеровані від 0 до 127. У цьому форматі використовуються цифри, латинські літери, розділові знаки та керуючі символи (наприклад, '\n', '\t', '\r').
ASCII – що це?
Таблиця ASCII (АСКИ) була розроблена в США у 60-х роках, і її назва перекладається як Американське стандартне кодування для обміну інформацією.
Існують національні розширення системи, що кодують символи та літери, прийняті в іноземних алфавітах. Вони замінено лише частина символів, наприклад, знак долара – на фунт. Для нелатинських алфавітів замінюється велика кількість символів. Російська належить до них.
Навіщо потрібна таблиця ASCII
За замовчуванням комп'ютери та смартфони не сприймають символи — лише числа, тому всі знаки кодуються, щоб комп'ютер розумів відповідність між накресленням та числовим значенням. ASCII є одним із ранніх кодувань, сьогодні існує кілька варіантів. З таблиці символів ASCII було взято стандарти інших рішень.
Це кодування було розроблено для телетайпів – пристроїв для обміну інформацією, якими сьогодні не користуються, залишилися лише деякі стандарти. ASCII кодує дані в комп'ютерних пристроях, використовується у творчості – з її допомогою створюються картинки. Це називають ASCII art.
Акція діє до 31 січня 2025 року включно
Застосування на практиці
Ось кілька варіантів практичного застосування:
- При розробках інтернет-ресурсів та програм розробникам ASCII необхідно для кодування символів, які не входять до національного кодування.
- ASCII дозволяє зберігати файли у закодованому вигляді. Це потрібно для передачі інформації, але деякі функції форматування будуть недоступні в цьому режимі.
- ASCII код вводиться з клавіатури безпосередньо при натисканні Alt та наборі числового значення, що відповідає символу з таблиці. У такий спосіб можна надрукувати такі символи: ієрогліфи, смайлики, літери алфавітів інших країн та ін.
Як влаштована система
ASCII дозволяє вводити, виводити та передавати інформацію. Таблиця використовується на 8 біт, а числа переводять у двійковий код для можливості розпізнавати знаки комп'ютером. Десятичне відтворення зрозуміліше для людей. Шістнадцяткове дозволяє оформляти набори у формі таблиці.
Великі літери та малі в системі є різними елементами. Перші знаходяться над другим на різних рядках, так простіше працювати з даними.
Як розташовуються символи ASCII у таблиці
- 1 та 2 рядки є керуючими символами.
- У 3 рядку – розділові знаки і спецсимволи (%, * і ін.).
- 4 рядок – арифметичні знаки, знак питання, крапка з комою, двокрапка.
- 5 і 6 рядки – великі літери та певні символи.
- 7 і 8 рядки — малі літери та символи.
Відмінності ASCII з Unicode
Це система кодування міжнародного рівня, в ній більше символів, ніж ASCII. У звичайній версії ASCII всього 128 символів, є розширення для інших мов, а в Unicode — понад 2 мільйони, вона включає всі символи, якими користуються у світі.Її можна назвати розширенням ASCII.
Для того, щоб грамотно використовувати ASCII, необхідно розширити знання в даній сфері та можливості кодування.
Оновлено: 2024-01-24 18:32:49 Віталій Черкасов автор матеріалу
Що таке?
ASCII є кодувальною таблицею друкованих символів (див. скріншот №1), що набираються на комп'ютерній клавіатурі, для передачі інформації та деяких кодів. Іншими словами відбувається кодування алфавіту та десяткових цифр у відповідні символи, що представляють та несуть у собі необхідну інформацію.
Кодування ASCII було розроблено в Америці, тому стандартна кодувальна таблиця зазвичай включає англійський алфавіт з цифрами, що в цілому становить близько 128 символів. Але тоді виникає справедливе питання: що робити, якщо необхідне кодування національного алфавіту?
Для вирішення подібних питань було розроблено інші версії таблиці ASCII. Наприклад, для мов з іншомовною структурою були або прибрані літери англійського алфавіту, або до них додавалися додаткові символи у вигляді національного алфавіту. Так, у кодуванні ASCII можуть бути російські літери для національного використання (див. скріншот №2).
Трюки на клавіатурі, які суттєво прискорюють роботу на комп'ютері.
Де використовується система кодування ASCII?
Ця система кодування необхідна не тільки для набору текстової інформації на клавіатурі. Вона також використовується у графіку. Наприклад, у програмі ASCII Art Maker графічні зображення різних розширень складаються із спектру символів кодування ASCII (див. скріншот №3).
Як правило, подібні програми можна розділити на ті, що виконують функцію графічних редакторів, інвертуючи зображення в текст, і ті, що конвертують зображення в ASCII -графіку. Всім відомий смайлик (або як його ще називають «усміхнене людське обличчя») теж є прикладом символу кодування.
Цей метод кодування також може бути потрібний під час написання або створення документа HTML. Наприклад, ви вводите певний і необхідний вам набір знаків, а під час перегляду самої сторінки на екран буде виведено символ, відповідний коду.
Крім усього іншого, даний вид кодування необхідний при створенні багатомовного сайту, тому що знаки, які не входять в ту чи іншу національну таблицю, потрібно буде замінити ASCII кодами. Якщо читач безпосередньо пов'язаний з інформаційно-комунікативними технологіями (ІКТ), йому буде корисно ознайомитися і з такими системами як:
- Набір символів, що переноситься;
- Керуючі символи;
- EBCDIC;
- VISCII;
- YUSCII;
- Юнікод;
- ASCII art;
- КОІ-8.
Властивості таблиці ASCII
Як і будь-яка систематизована програма, ASCII має свої характерні властивості. Так, наприклад, десятична система обчислення (цифри від 0 до 9) перетворюється на двійкову систему обчислення (тобто кожна десятична цифра перетворюється на двійкову 288=1001000 відповідно).
Літери, що розташовуються у верхніх і нижніх колонках, відрізняються один від одного лише бітом, що суттєво знижує рівень складності перевірки та редагування регістру.
При всіх цих властивостях кодування ASCII працює як восьми бітне, хоча спочатку передбачалося як семи бітове.
Застосування ASCII у програмах Microsoft Office:
У разі потреби цей варіант кодування інформації може бути використаний у Microsoft Notepad та Microsoft Office Word. У цих програмах документ може бути збережений у форматі ASCII , але в цьому випадку при наборі тексту неможливо буде використовувати деякі функції.
Зокрема, буде недоступне виділення жирним та напівжирним шрифтом, тому що кодування зберігає лише сенс набраної інформації, а не загальний вигляд та форму. Додати такі коди в документ можна за допомогою таких програмних додатків:
- Microsoft Excel;
- Microsoft FrontPage;
- Microsoft InfoPath;
- Microsoft OneNote;
- Microsoft Outlook;
- Microsoft PowerPoint;
- Microsoft Project.
При цьому варто враховувати, що набираючи код ASCII у цих додатках, необхідно утримувати натиснутою клавіатурну клавішу ALT.
Звичайно, всі необхідні коди потребують більш тривалого та ґрунтовного вивчення, але це виходить за межі нашої сьогоднішньої статті. Сподіваюся, що вона виявилася для Вас справді корисною.