Чому англійські символи потребують меншої кількості байтів, ніж інші алфавіти?


30

Коли я поміщаю "a" у текстовий файл, він робить його 2 байти, але коли я ставимо, скажімо, "ա", що є буквою вірменського алфавіту, це робить 3 байти.

Яка різниця між алфавітами для комп’ютера?
Чому англійська займає менше місця?


22
Ви повинні прочитати цю статтю засновника StackExchange: joelonsoftware.com/articles/Unicode.html
Ерік Ліпперт

22
Я не думаю, що існує таке поняття, як "англійські символи". Вони римські.
Рафаель

5
@Raphael усі знають, про що він має на увазі. Але приємно додати.
Mathias Lykkegaard Lorenzen

1
@Raphael Насправді існує багато римських букв, які не використовуються англійською мовою, і тому вони не включені до набору символів ASCII. Більшість з них включає модифікатори, але вони все ще потрібні для належного відображення тексту на різних латинських мовах, окрім англійської.
Wutaz

7
@Raphael Я не думаю, що існує таке поняття, як "римські персонажі". Вони латинські.
Blacklight Shining

Відповіді:


41

Однією з перших схем кодування, розробленою для використання в комп'ютерах, є стандарт ASCII ( Американський стандартний код для обміну інформацією ). Він був розроблений в 60-х роках у США.

В англійському алфавіті використовується частина латинського алфавіту (наприклад, в англійській мові є кілька наголошених слів). У цьому алфавіті є 26 окремих літер, не враховуючи регістру. І також повинні були існувати окремі числа та розділові знаки в будь-якій схемі, яка претендує на кодування англійського алфавіту.

1960-ті роки також були часом, коли на комп’ютерах не було обсягу пам'яті чи дискового простору, який ми маємо зараз. ASCII був розроблений як стандартне представлення функціонального алфавіту на всіх американських комп'ютерах. На той час рішення про те, щоб кожен символ ASCII становив 8 біт (1 байт), було прийнято завдяки технічним деталям того часу (у статті Вікіпедії згадується той факт, що перфорована стрічка утримувала 8 біт за один раз). Насправді, оригінальну схему ASCII можна передавати за допомогою 7 біт, вісім можна використовувати для перевірки парності. Пізніші розробки розширили оригінальну схему ASCII, включаючи кілька наголошених, математичних та термінальних символів.

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

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

UTF-8 - це один із способів кодування набору символів Unicode. Це кодування змінної ширини (наприклад, різні символи можуть мати різний розмір) і було розроблено для зворотної сумісності з колишньою схемою ASCII. Таким чином, набір символів ASCII залишатиметься одним байтом, тоді як будь-які інші символи мають два та більше байти. UTF-16 - ще один спосіб кодування набору символів Unicode. На відміну від UTF-8 символи кодуються як набір одного або двох 16-бітних одиниць коду.

Як зазначено в коментарях, символ "a" займає один байт, тоді як "ա" займає два байти, що позначає кодування UTF-8. Додатковий байт у вашому запитанні був обумовлений наявністю символу нового рядка в кінці (про що дізналася ОП).


26
Немає останнього байта, який кодує кінець файлу, у будь-якому звичайному кодуванні чи форматі файлу. Коли програма читає файл, ОС може сигналізувати про закінчення файлу спеціальним чином, але це інша проблема.
Jukka K. Korpela

2
Символ ա - 2 байти (0xD5A1) у версії UTF-8 унікоду; зайвий символ (що б там не було) присутній в обох файлах. marathon-studios.com/unicode/U0561/Armenian_Small_Letter_Ayb
Dan Neely

6
@khajvah Якщо ви echo 'ա' > file.txtце редагуєте або редагуєте файл за допомогою деяких редакторів, вони автоматично додають новий рядок після нього. Якщо ви запустите xxd file.txt, останнім байтом, ймовірно, буде 0aканал або рядок.
Даніель Бек

7
@DoktoroReichard: Будь ласка, уточніть у відповідь, що Unicode не є кодуванням; скоріше, це абстрактний набір символів, і UTF-16 і UTF-8 є кодуванням кодових точок Unicode. Останні пункти вашої відповіді здебільшого говорять про UTF-8. Але якщо для файлу використовується UTF-16, то будь-яка кодова точка, навіть та для a, буде використовувати два байти (або кратне два).
grawity

6
Також, напевно, варто підкреслити, що "розширений ASCII" набір символів насправді зовсім не ASCII, а кількість різних способів використання восьмого біта робить це все великим безладом. Просто використовуйте UTF-8 замість цього.
ntoskrnl

17

1 байт - це 8 біт, і таким чином може представляти до 256 (2 ^ 8) різних значень.

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

Зауважте, що зазвичай більшість кодувань використовують перші 7 біт (128 значень) для символів ASCII . Це залишає 8-й біт, або 128 значень для більшої кількості символів. . . додайте в наголошені символи, азіатські мови, кирилицю тощо, і ви легко зрозумієте, чому 1 байт недостатньо для збереження всіх символів.


тож ось єдина відповідь, яка фактично пояснює, чому використовується більше місця
Фелікс Ганьон-Греньє,

10

У UTF-8 символи ASCII використовують один байт, інші символи використовують два, три чи чотири байти.


1
Чи можете ви детальніше пояснити, чому це так? зазначення двох методів кодування не зовсім відповідає на питання.
MaQleod

@MaQleod Unicode був створений для заміни ASCII. Для зворотної сумісності перші 128 символів однакові. Ці 128 символів можна виразити одним байтом. Для додаткових символів додаються додаткові байти.
Джейсон

Я знаю, але це частина відповіді на питання про те, що робить символи ASCII різними. Це слід пояснити ОП.
MaQleod

@MaQleod Можна також сказати, що консорціум Unicode в основному складався з американських корпорацій і був упереджений до символів англійської мови. Я вважав, що проста відповідь - краща за суб’єктивну.
Джейсон

15
Не "в Unicode", а в UTF8 - це лише одне з декількох кодувань набору символів Unicode.
Себастьян Неграш

3

Кількість байтів, необхідних для символу (про який, мабуть, йдеться), залежить від кодування символів. Якщо ви використовуєте кодування ArmSCII, кожна армянська літера займає лише один байт. Але це не вдалий вибір сьогодні.

У кодуванні передачі UTF-8 для Unicode символам потрібно різна кількість байтів. У ньому “a” бере лише один байт (ідея про два байти - це якась плутанина), “á” займає два байти, а армянська буква ayb “ա” також займає два байти. Три байти повинні бути певною плутаниною. На відміну, наприклад, бенгальська літера "a" займає три байти в UTF-8.

Передумовою є просто те, що UTF-8 був розроблений таким чином, щоб бути дуже ефективним для персонажів Ascii, досить ефективним для систем письма в Європі та оточенні, а все інше менш ефективно. Це означає, що основні латинські літери (з яких здебільшого складається англійський текст) для символу потрібен лише один байт; для грецької, кириличної, вірменської та кількох інших потрібні два байти; все інше потребує більше.

UTF-8 має (як зазначено в коментарі) також корисну властивість, що дані Ascii (коли вони представлені у вигляді 8-бітових одиниць, що є майже єдиним способом протягом тривалого часу), також тривіально кодується UTF-8.


Дякую за відповідь. Додаткові байти - це тому, що програма, яку я використав, автоматично додала новий символ рядка до кінця.
хаджва

1
Я не думаю, що UTF-8 був розроблений не настільки ефективно для даних ASCII, скільки для сумісності . У UTF-8 є дуже приємна властивість, що 7-бітний вміст ASCII (з високим бітом, встановленим нулем) ідентичний тому самому вмісту, кодованому як UTF-8, тому для інструментів, які зазвичай мають справу з ASCII, це замінна плата . Наскільки мені відомо, жодна інша схема кодування Unicode не має цієї властивості. UTF-8 також досить компактний для більшості даних, особливо якщо ви залишаєтесь у царині BMP Unicode .
CVn

1
@ MichaelKjörling, я додав посилання на цю функцію. Однак головним запереченням Unicode в перші дні була неефективність, і UTF-16 вдвічі збільшує розмір даних, який є домінантою Ascii. UTF-8 означає, наприклад, за англійський текст, що ви "платите" лише за символи, які ви не використовуєте Ascii.
Jukka K. Korpela

3

Коди символів у 1960-х (і довше) були специфічними для машини. У 1980-х я коротко використовував машину DEC 2020, яка мала 36 бітових слів і 5, 6 та 8 ( IIRC ) біт на кодування символів. До цього я використовував серію IBM 370 з EBCDIC. ASCII із 7 бітами наводив порядок, але він заплутався з "кодовими сторінками" IBM PC, використовуючи всі 8 біт для представлення зайвих символів, як усі види малювання коробки для малювання примітивних меню, а пізніше розширення ASCII, як Latin-1 (8 біт кодування, з першими 7 бітами, як ASCII, а другою половиною для "національних символів", наприклад ñ, Çтощо. Напевно, найпопулярнішою була латинська-1, пристосована до англійської та більшості європейських мов, використовуючи латинські символи (і наголоси та варіанти).

Написання змішування тексту, наприклад, англійська та іспанська мови, пішло нормально (просто використовуйте латинську-1, суперсети обох), але змішування всього, що використовувало інше кодування (скажімо, включає фрагмент грецької чи російської, не кажучи вже про азіатську мову, як японська) справжній кошмар. Найгірше було те, що російські, а особливо японські та китайські, мали кілька популярних, абсолютно несумісних кодувань.

Сьогодні ми використовуємо Unicode, який поєднується з ефективними кодуваннями, такими як UTF-8, які надають перевагу англійським символам (на диво, кодування англійських літер так само відповідає, що відповідає ASCII), завдяки чому багато неанглійських символів використовують довші кодування.


2

Файл Windows 8.1 з США та англійською мовою з єдиним "a", збереженим у блокноті.

  • Збережіть як ANSI 1 байт
  • Збережіть AS Unicode 4 байти
  • Збережіть AS UTF-8 4 байти

Файл із єдиною 'ա', збереженою у блокноті

  • Зберегти AS ANSI неможливо
  • Збережіть AS Unicode 4 байти
  • Збережіть AS UTF-8 5 байт

Один 'a' кодується як один байт в ANSI, в Unicode кожен символ, як правило, 2 байти, також є 2-байтний BOM (маркер порядку в байтах) на початку файлу. UTF-8 має 3-байтний BOM і однобайтовий символ.

Для 'ա' цей символ не існує в наборі символів ANSI і його неможливо зберегти на моїй машині. Файл Unicode такий же, як і раніше, а файл UTF-8 на 1 байт більший, оскільки символ займає 2 байти.

Якщо ваша машина з іншого регіону, у вас може бути інша кодова сторінка OEM, яка має різні гліфи для 255 символів, можливих в діапазоні ASCII. Як згадував @ntoskrnl, кодовою сторінкою OEM для моєї машини буде Windows-1252, що є стандартною для англійської США.


4
Блокнот (і Windows взагалі) тут використовує заплутану термінологію. "ANSI" - це однобайтове кодування, що залежить від локальної локалізації (Windows-1252 в англійських версіях), а "Unicode" - UTF-16.
ntoskrnl

@ntoskrnl Це правильно, але якщо ви шукаєте у випадаючому полі для кодування, він пише ANSI, саме тому я згадав, якщо у вас інша кодова сторінка OEM, ви можете отримати різні результати.
Darryl Braaten

2

Якщо вас цікавить, як зберігаються символи, ви можете зайти на www.unicode.org і подивитися. Угорі їх головної сторінки - посилання "Діаграми коду", яке показує всі коди символів, які доступні в Unicode.

Загалом в Unicode є трохи більше мільйона кодів (не всі вони використовуються). Один байт може вмістити 256 різних значень, тож вам потрібно три байти, якщо ви хочете зберігати всі можливі коди Unicode.

Натомість Unicode зазвичай зберігається в кодуванні "UTF-8", який використовує менше байтів для деяких символів і більше для інших. Перші 128 значень коду зберігаються в одному байті, до перших 2048 значень коду зберігаються в двох байтах, до 65536 зберігаються в трьох байтах, а решта займають чотири байти. Це влаштовано так, що значення коду, які використовуються частіше, займають менше місця. AZ, az, 0-9 і! @ $% ^ & * () - [} {}; ': "|,. / <>? І деякі, що я забув, беруть один байт; майже всю англійську, 98% Німецька та французька мови (лише здогадки) можуть зберігатися в одному байті на символ, і це символи, які використовуються найбільше. Кирилиця, грецька, іврит, арабська та деякі інші використовують два байти на символ. Індійські мови, більшість китайської, японської , Корейська, тайська, тонн математичних символів, можна записати в трьох байтах на символ. Рідкісні речі (якщо ви хочете коли-небудь писати текст у лінійній A або лінійній B, Emojis) беруть чотири байти.

Ще одне кодування - UTF-16. Все, що займає 1, 2 або 3 байти в UTF-8, займає два байти в UTF-16. Це перевага, якщо у вас є китайський або японський текст з дуже мало латинських символів між ними.

Про причини дизайну UTF-8: Він має ряд переваг перед іншими конструкціями. Вони є:

Сумісність із символами US-ASCII

Розумна компактність

Самосинхронізація: Це означає, що якщо вам надана частина послідовності байтів, що є символами кодування UTF-8, ви можете дізнатися, з чого починається символ. У деяких кодуваннях і xy, і yx можуть бути дійсними кодуваннями символів, тому, якщо вам надано частину послідовності ... xyxyxyxyxyxy ... ви не можете знати, які символи у вас є.

Правильність сортування: Якщо ви сортуєте рядки, що містять кодовані символи UTF-8, за байтовими значеннями, то вони автоматично сортуються правильно відповідно до їх значень Unicode.

Сумісний з однобайтовим кодом: Більшість кодів, що передбачає однобайтові значення, автоматично працює правильно з кодованими символами UTF-8.

Плюс із будь-яких причин я забув.

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