Kodowanie znaków

Dziurkowana taśma ze słowem „Wikipedia” zakodowanym w ASCII . Obecność i brak dziury oznacza odpowiednio 1 i 0; na przykład „W” jest zakodowane jako „1010111”.

Kodowanie znaków to proces przypisywania liczb znakom graficznym , zwłaszcza pisanym znakom ludzkiego języka , umożliwiający ich przechowywanie , przesyłanie i przekształcanie za pomocą komputerów cyfrowych . Wartości liczbowe składające się na kodowanie znaków są znane jako „ punkty kodowe ” i łącznie składają się na „przestrzeń kodową”, „ stronę kodową ” lub „ mapę znaków ”.

Wczesne kody znaków związane z telegrafem optycznym lub elektrycznym mogły reprezentować tylko podzbiór znaków używanych w językach pisanych , czasami ograniczone tylko do wielkich liter , cyfr i niektórych znaków interpunkcyjnych . Niski koszt cyfrowej reprezentacji danych w nowoczesnych systemach komputerowych pozwala na stosowanie bardziej rozbudowanych kodów znaków (takich jak Unicode ), które reprezentują większość znaków używanych w wielu językach pisanych. Kodowanie znaków przy użyciu międzynarodowych standardów umożliwia wymianę tekstu w formie elektronicznej na całym świecie.

Historia

Historia kodów znaków ilustruje ewoluujące zapotrzebowanie na informacje symboliczne oparte na znakach, za pośrednictwem maszyn, na odległość, przy użyciu niegdyś nowatorskich środków elektrycznych. Najwcześniejsze kody były oparte na ręcznych i pisanych odręcznie systemach kodowania i szyfrowania, takich jak szyfr Bacona , Braille'a , międzynarodowe morskie flagi sygnałowe oraz 4-cyfrowe kodowanie chińskich znaków dla chińskiego kodu telegraficznego ( Hans Schjellerup , 1869). Wraz z przyjęciem technik elektrycznych i elektromechanicznych te najwcześniejsze kody zostały dostosowane do nowych możliwości i ograniczeń wczesnych maszyn. Najwcześniejszy dobrze znany kod znaków przesyłanych elektrycznie, kod Morse'a , wprowadzony w latach czterdziestych XIX wieku, wykorzystywał system czterech „symboli” (krótki sygnał, długi sygnał, krótka spacja, długa spacja) do generowania kodów o zmiennej długości. Chociaż niektóre komercyjne zastosowania alfabetu Morse'a odbywały się za pomocą maszyn, był on często używany jako kod ręczny, generowany ręcznie na kluczu telegraficznym i możliwy do odczytania przez ucho, i utrzymuje się w amatorskim radiu i lotnicze . Większość kodów ma stałą długość na znak lub sekwencje o zmiennej długości kodów o stałej długości (np. Unicode ).

Typowe przykłady systemów kodowania znaków obejmują alfabet Morse'a , kod Baudota , amerykański standardowy kod wymiany informacji ( ASCII ) i Unicode . Unicode , dobrze zdefiniowany i rozszerzalny system kodowania, wyparł większość wcześniejszych kodowań znaków, ale ścieżka rozwoju kodu do chwili obecnej jest dość dobrze znana.

Kod Baudota , kodowanie pięciobitowe, został stworzony przez Émile'a Baudota w 1870 r., Opatentowany w 1874 r., Zmodyfikowany przez Donalda Murraya w 1901 r. I znormalizowany przez CCITT jako międzynarodowy alfabet telegraficzny nr 2 (ITA2) w 1930 r. Nazwa „baudot ” został błędnie zastosowany do ITA2 i jego wielu wariantów. ITA2 miał wiele niedociągnięć i był często „ulepszany” przez wielu producentów sprzętu, czasami powodując problemy ze zgodnością. W 1959 roku wojsko USA zdefiniowało swoje Fieldata kod, sześcio- lub siedmiobitowy kod, wprowadzony przez US Army Signal Corps. Podczas gdy Fieldata zajmował się wieloma współczesnymi wówczas problemami (np. kodami literowymi i cyfrowymi przeznaczonymi do zestawiania maszynowego), Fieldata nie osiągnął swoich celów i był krótkotrwały. W 1963 roku komitet ASCII (w skład którego wchodził co najmniej jeden członek komitetu Fieldata, WF Leubbert) wydał pierwszy kod ASCII (American Standard Code for Information Interchange) (X3.4-1963), który rozwiązał większość niedociągnięć Fieldata , używając prostszego kodu. Wiele zmian było subtelnych, takich jak zestawiane zestawy znaków w określonych zakresach liczbowych. ASCII63 odniósł sukces, szeroko przyjęty przez przemysł, a wraz z kolejnym wydaniem kodu ASCII z 1967 r. (Który dodał małe litery i naprawił niektóre problemy z „kodem kontrolnym”), ASCII67 został przyjęty dość powszechnie. Amerykańsko-centryczny charakter ASCII67 został w pewnym stopniu uwzględniony w Europie ECMA-6 .

Hollerith 80-kolumnowa karta perforowana z zestawem znaków EBCDIC

Herman Hollerith wynalazł kodowanie danych z kart perforowanych pod koniec XIX wieku w celu analizy danych spisowych. Początkowo każda pozycja otworu reprezentowała inny element danych, ale później informacje liczbowe zostały zakodowane poprzez numerowanie dolnych rzędów od 0 do 9, z dziurkaczem w kolumnie reprezentującym numer wiersza. Późniejsze dane alfabetyczne zostały zakodowane, umożliwiając więcej niż jedno uderzenie na kolumnę. Elektromechaniczne maszyny do tworzenia tabel przedstawiały datę wewnętrznie na podstawie synchronizacji impulsów w stosunku do ruchu kart przez maszynę. Kiedy IBM przeszedł do przetwarzania elektronicznego, zaczynając od IBM 603 Electronic Multiplier, wykorzystywał różne schematy kodowania binarnego, które były powiązane z kodem karty perforowanej.

IBM Binary Coded Decimal ( BCD ) był sześciobitowym schematem kodowania używanym przez IBM już w 1953 roku w komputerach 702 i 704 , a także w późniejszych seriach 7000 i 1400 , a także w powiązanych urządzeniach peryferyjnych. Ponieważ używany wówczas kod karty perforowanej dopuszczał tylko cyfry, duże litery angielskie i kilka znaków specjalnych, wystarczyło sześć bitów. BCD rozszerzył istniejące proste czterobitowe kodowanie numeryczne o znaki alfabetyczne i specjalne, łatwo odwzorowując je na kodowanie kart perforowanych, które było już w powszechnym użyciu. Kody IBM były używane głównie ze sprzętem IBM; inni dostawcy komputerów tamtej epoki mieli własne kody znaków, często sześciobitowe, ale zwykle mieli możliwość odczytu taśm wyprodukowanych na sprzęcie IBM. BCD był prekursorem IBM Extended Binary Coded Decimal Interchange Code (zwykle w skrócie EBCDIC), ośmiobitowy schemat kodowania opracowany w 1963 roku dla IBM System/360 , który zawierał większy zestaw znaków, w tym małe litery.

Wkrótce ujawniły się ograniczenia takich zestawów, [ dla kogo? ] i opracowano szereg metod ad hoc w celu ich rozszerzenia. Potrzeba obsługi większej liczby systemów pisma dla różnych języków, w tym rodziny skryptów wschodnioazjatyckich CJK , wymagała obsługi znacznie większej liczby znaków i wymagała systematycznego podejścia do kodowania znaków, a nie poprzednich podejść ad hoc . [ potrzebne źródło ]

Próbując opracować uniwersalnie wymienne kodowanie znaków, naukowcy w latach 80. stanęli przed dylematem, że z jednej strony wydawało się konieczne dodanie większej liczby bitów, aby pomieścić dodatkowe znaki, ale z drugiej strony dla użytkowników stosunkowo małego zestawu znaków alfabetu łacińskiego (którzy nadal stanowili większość użytkowników komputerów), te dodatkowe bity były kolosalnym marnotrawstwem rzadkich wówczas i kosztownych zasobów obliczeniowych (ponieważ zawsze byłyby wyzerowane dla takich użytkowników). W 1985 r. dysk twardy przeciętnego użytkownika komputera osobistego mógł przechowywać tylko około 10 megabajtów i kosztował około 250 USD na rynku hurtowym (i znacznie więcej, jeśli był kupowany osobno w sprzedaży detalicznej), więc w tamtym czasie bardzo ważne było, aby każdy bit się liczył.

Rozwiązaniem kompromisowym, które ostatecznie zostało znalezione i opracowane w Unicode, było złamanie założenia (pochodzącego z kodów telegraficznych), że każdy znak powinien zawsze bezpośrednio odpowiadać określonej sekwencji bitów. Zamiast tego znaki byłyby najpierw odwzorowywane na uniwersalną reprezentację pośrednią w postaci abstrakcyjnych liczb zwanych punktami kodowymi . Punkty kodowe byłyby wtedy reprezentowane na różne sposoby iz różnymi domyślnymi liczbami bitów na znak (jednostki kodu) w zależności od kontekstu. Aby zakodować punkty kodowe większe niż długość jednostki kodu, na przykład powyżej 256 dla jednostek ośmiobitowych, rozwiązaniem było wdrożenie kodowania o zmiennej długości , w których sekwencja ucieczki sygnalizowałaby, że kolejne bity powinny być analizowane jako wyższy punkt kodowy.

Terminologia

Terminologia związana z kodowaniem znaków
KB Dubeolsik for Old Hangul (NG3).svg
  • Znak to minimalna jednostka tekstu, która ma wartość semantyczną .
  • Zestaw znaków to zbiór znaków, które mogą być używane w wielu językach. Przykład: Zestaw znaków łacińskich jest używany w języku angielskim i większości języków europejskich, chociaż zestaw znaków greckich jest używany tylko w języku greckim.
  • Zakodowany zestaw znaków to zestaw znaków, w którym każdy znak odpowiada unikalnej liczbie.
  • Punkt kodowy zakodowanego zestawu znaków to dowolna dozwolona wartość w zestawie znaków lub przestrzeni kodowej.
  • Przestrzeń kodowa to zakres liczb całkowitych, których wartości są punktami kodowymi.
  • Jednostka kodu to „rozmiar słowa” schematu kodowania znaków, na przykład 7-bitowy, 8-bitowy, 16-bitowy. W niektórych schematach niektóre znaki są kodowane przy użyciu wielu jednostek kodu, co skutkuje kodowaniem o zmiennej długości. jednostka kodu jest określana jako wartość kodu .
Repertuar postaci (abstrakcyjny zestaw postaci)

Repertuar znaków to abstrakcyjny zestaw ponad miliona znaków występujących w wielu różnych pismach, w tym łacińskim, cyrylicy, chińskim, koreańskim, japońskim, hebrajskim i aramejskim.

W repertuarze postaci znajdują się również inne symbole, takie jak notacja muzyczna. Zarówno standardy Unicode, jak i GB 18030 mają repertuar znaków. Gdy nowe znaki są dodawane do jednego standardu, drugi standard również dodaje te znaki, aby zachować parzystość.

Rozmiar jednostki kodu odpowiada pomiarowi bitu dla konkretnego kodowania:

  • Jednostka kodu w US-ASCII składa się z 7 bitów;
  • Jednostka kodu w UTF-8 , EBCDIC i GB 18030 składa się z 8 bitów;
  • Jednostka kodu w UTF-16 składa się z 16 bitów;
  • Jednostka kodu w UTF-32 składa się z 32 bitów.
Przykład jednostki kodu

Rozważ ciąg liter „ab̲c𐐀”, to znaczy ciąg zawierający znak łączący Unicode ( U+0332 ̲ ) oraz znak dodatkowy ( U+10400 𐐀 ). Ten ciąg ma kilka reprezentacji, które są logicznie równoważne, ale każda z nich jest dostosowana do różnych okoliczności lub zakresu wymagań:

  • Cztery złożone znaki :
    a , , c , 𐐀
  • Pięć grafemów :
    a , b , _ , c , 𐐀
  • Pięć punktów kodowych Unicode :
    U+0061 , U+0062 , U+0332 , U+0063 , U+10400
  • Pięć jednostek kodu UTF-32 (32-bitowe wartości całkowite):
    0x00000061 , 0x00000062 , 0x00000332 , 0x00000063 , 0x00010400
  • Sześć jednostek kodu UTF-16 (16-bitowe liczby całkowite)
    0x0061 , 0x0062 , 0x0332 , 0x0063 , 0xd801 , 0xdc00
  • Dziewięć jednostek kodu UTF-8 (wartości 8-bitowe lub bajty )
    0x61 , 0x62 , 0xCC , 0xB2 , 0x63 , 0xf0 , 0x90 , 0x90 , 0x80

Zwróć szczególną uwagę na ostatni znak, który jest reprezentowany przez jedną wartość 32-bitową lub dwie wartości 16-bitowe. lub 4 wartości 8-bitowe. Chociaż każda z tych form używa tej samej całkowitej liczby bitów (32) do reprezentowania glifu, rzeczywiste numeryczne wartości bajtów i ich rozmieszczenie wydają się całkowicie niezwiązane.

Punkt kodu

Konwencja odnosząca się do znaku w Unicode polega na rozpoczynaniu od „U+”, po którym następuje wartość punktu kodowego w systemie szesnastkowym. Zakres prawidłowych punktów kodowych dla standardu Unicode wynosi od U+0000 do U+10FFFF włącznie, podzielony na 17 płaszczyzn , oznaczonych cyframi od 0 do 16. Znaki z zakresu od U+0000 do U+FFFF znajdują się na płaszczyźnie 0, o nazwie Basic Multilingual Plane (BMP). Ta płaszczyzna zawiera najczęściej używane znaki. Znaki z zakresu od U+10000 do U+10FFFF w pozostałych płaszczyznach nazywane są znakami uzupełniającymi .

W poniższej tabeli przedstawiono przykłady wartości punktów kodowych:

Postać Punkt kodu Unicode glif
łaciński A U+0041 Α
Łaciński ostry S U+00DF SS
Han dla Wschodu U+6771
Ampersand U+0026 &
Odwrócony wykrzyknik U+00A1 ¡
Znak sekcji U+00A7 §

Punkt kodowy jest reprezentowany przez sekwencję jednostek kodu. Mapowanie jest definiowane przez kodowanie. Zatem liczba jednostek kodu wymaganych do reprezentacji punktu kodowego zależy od kodowania:

  • UTF-8: punkty kodowe odwzorowują sekwencję jednej, dwóch, trzech lub czterech jednostek kodu.
  • UTF-16: jednostki kodu są dwa razy dłuższe niż jednostki kodu 8-bitowego. Dlatego każdy punkt kodowy o wartości skalarnej mniejszej niż U+10000 jest kodowany za pomocą pojedynczej jednostki kodu. Punkty kodowe o wartości U+10000 lub wyższej wymagają dwóch jednostek kodu. Te pary jednostek kodu mają unikalny termin w UTF-16: „Pary zastępcze Unicode”.
  • UTF-32: 32-bitowa jednostka kodu jest wystarczająco duża, aby każdy punkt kodu był reprezentowany jako pojedyncza jednostka kodu.
  • GB 18030: wiele jednostek kodu na punkt kodowy jest powszechnych ze względu na małe jednostki kodu. Punkty kodowe są mapowane na jedną, dwie lub cztery jednostki kodu.

Model kodowania Unicode

Unicode i jego równoległy standard, uniwersalny zestaw znaków ISO/IEC 10646 , razem tworzą nowoczesne, ujednolicone kodowanie znaków. Zamiast odwzorowywać znaki bezpośrednio na oktety ( bajty ), osobno określają, jakie znaki są dostępne, odpowiadające im liczby naturalne ( punkty kodowe ), sposób kodowania tych liczb jako serię liczb naturalnych o stałym rozmiarze (jednostki kodowe) i wreszcie, w jaki sposób te liczby jednostki są kodowane jako strumień oktetów. Celem tej dekompozycji jest ustalenie uniwersalnego zestawu znaków, które można zakodować na różne sposoby. Prawidłowe opisanie tego modelu wymaga bardziej precyzyjnych terminów niż „zestaw znaków” i „kodowanie znaków”. Terminy używane w nowoczesnym modelu są następujące:

Repertuar znaków to pełny zestaw abstrakcyjnych znaków obsługiwanych przez system. Repertuar może być zamknięty, tzn. żadne dodatki nie są dozwolone bez tworzenia nowego standardu (jak ma to miejsce w przypadku ASCII i większości serii ISO-8859), lub może być otwarty, dopuszczając dodatki (jak w przypadku Unicode i do w ograniczonym zakresie strony kodowe systemu Windows ). Postacie w danym repertuarze odzwierciedlają podjęte decyzje dotyczące podziału systemów pisma na podstawowe jednostki informacyjne. Podstawowe odmiany łaciny , greki i cyrylicy alfabety można podzielić na litery, cyfry, znaki interpunkcyjne i kilka znaków specjalnych , takich jak spacja, które można ułożyć w proste sekwencje liniowe, które są wyświetlane w tej samej kolejności, w jakiej zostały odczytane. Ale nawet w przypadku tych alfabetów znaki diakrytyczne stanowią komplikację: można je traktować albo jako część pojedynczego znaku zawierającego literę i znak diakrytyczny (znany jako znak złożony), albo jako oddzielne znaki. Pierwsza pozwala na znacznie prostszy system obsługi tekstu, ale druga pozwala na użycie w tekście dowolnej kombinacji liter/znaków diakrytycznych. Ligatury stwarzać podobne problemy. Inne systemy pisma, takie jak arabski i hebrajski, są reprezentowane przez bardziej złożone repertuary znaków ze względu na konieczność uwzględnienia takich rzeczy, jak tekst dwukierunkowy i glify , które są łączone na różne sposoby w różnych sytuacjach.

Kodowany zestaw znaków (CCS) to funkcja , która odwzorowuje znaki na punkty kodowe (każdy punkt kodowy reprezentuje jeden znak). Na przykład w danym repertuarze wielka litera „A” w alfabecie łacińskim może być reprezentowana przez punkt kodowy 65, znak „B” do 66 i tak dalej. Wiele zakodowanych zestawów znaków może mieć ten sam repertuar; na przykład ISO / IEC 8859-1 i strony kodowe IBM 037 i 500 obejmują ten sam repertuar, ale odwzorowują je na różne punkty kodowe.

Forma kodowania znaków (CEF) to mapowanie punktów kodowych na jednostki kodowe w celu ułatwienia przechowywania w systemie, który przedstawia liczby jako sekwencje bitów o stałej długości (tj. praktycznie w każdym systemie komputerowym). Na przykład system, który przechowuje informacje liczbowe w jednostkach 16-bitowych, może bezpośrednio reprezentować tylko punkty kodowe od 0 do 65 535 w każdej jednostce, ale większe punkty kodowe (powiedzmy od 65 536 do 1,4 miliona) mogą być reprezentowane przy użyciu wielu jednostek 16-bitowych. Ta korespondencja jest zdefiniowana przez CEF.

Następnie schemat kodowania znaków (CES) to mapowanie jednostek kodu na sekwencję oktetów w celu ułatwienia przechowywania w systemie plików opartym na oktetach lub transmisji w sieci opartej na oktetach. Proste schematy kodowania znaków obejmują UTF-8 , UTF-16BE , UTF-32BE , UTF-16LE lub UTF-32LE ; schematy kodowania znaków złożonych, takie jak UTF-16 , UTF-32 i ISO/IEC 2022 , przełączają się między kilkoma prostymi schematami za pomocą znacznika kolejności bajtów lub sekwencje specjalne ; schematy kompresji próbują zminimalizować liczbę bajtów używanych na jednostkę kodu (takie jak SCSU , BOCU i Punycode ).

Chociaż UTF-32BE jest prostszym CES, większość systemów pracujących z Unicode używa albo UTF-8 , który jest wstecznie kompatybilny z ASCII o stałej długości i odwzorowuje punkty kodowe Unicode na sekwencje oktetów o zmiennej długości, albo UTF-16BE , który jest wsteczny kompatybilny z UCS-2BE o stałej długości i odwzorowuje punkty kodowe Unicode na sekwencje słów 16-bitowych o zmiennej długości. Zobacz porównanie kodowań Unicode, aby zapoznać się ze szczegółową dyskusją.

Wreszcie, może istnieć protokół wyższego poziomu , który dostarcza dodatkowych informacji w celu wybrania konkretnego wariantu znaku Unicode , szczególnie tam, gdzie istnieją warianty regionalne, które zostały „ujednolicone” w Unicode jako ten sam znak. Przykładem jest XML xml:lang.

Model Unicode używa terminu mapa znaków dla systemów historycznych, które bezpośrednio przypisują sekwencję znaków do sekwencji bajtów, obejmując wszystkie warstwy CCS, CEF i CES.

Zestawy znaków, mapy znaków i strony kodowe

Historycznie terminy „kodowanie znaków”, „mapa znaków”, „zestaw znaków” i „ strona kodowa ” były w informatyce synonimami , ponieważ ten sam standard określałby repertuar znaków i sposób ich kodowania w strumień jednostki kodu – zwykle z pojedynczym znakiem na jednostkę kodu. Ale teraz terminy mają powiązane, ale różne znaczenia, dzięki wysiłkom organów normalizacyjnych, aby używać precyzyjnej terminologii podczas pisania i ujednolicania wielu różnych systemów kodowania. Niezależnie od tego terminy są nadal używane zamiennie, z zestawem znaków będąc niemal wszechobecnym.

Strona kodowa ” zwykle oznacza kodowanie zorientowane na bajty , ale w odniesieniu do pewnego zestawu kodowań (obejmujących różne skrypty), w których wiele znaków ma te same kody na większości lub wszystkich tych stronach kodowych. Dobrze znane pakiety stron kodowych to „Windows” (oparty na Windows-1252) i „IBM”/„DOS” (oparty na stronie kodowej 437 ). Aby uzyskać szczegółowe informacje , zobacz stronę kodową systemu Windows . Większość, ale nie wszystkie kodowania określane jako strony kodowe to kodowania jednobajtowe (ale zobacz oktet na temat rozmiaru bajtów).

Architektura IBM Character Data Representation Architecture (CDRA) wyznacza jednostki z zakodowanymi identyfikatorami zestawów znaków ( CCSID ), z których każdy jest różnie nazywany „zestawem znaków”, „zestawem znaków”, „stroną kodową” lub „CHARMAP”.

Termin „strona kodowa” nie występuje w systemach Unix ani Linux, gdzie preferowana jest „charmap”, zwykle w szerszym kontekście ustawień regionalnych.

W przeciwieństwie do „ zakodowanego zestawu znaków ”, „kodowanie znaków” to mapa od abstrakcyjnych znaków do słów kodowych . „Zestaw znaków” w HTTP (i MIME ) jest taki sam jak kodowanie znaków (ale nie to samo co CCS).

Legacy kodowanie” to termin używany czasami do scharakteryzowania starych kodowań znaków, ale mający niejednoznaczny sens. Większość jego użycia jest w kontekście Unicodification , gdzie odnosi się do kodowania, które nie obejmuje wszystkich punktów kodowych Unicode lub, bardziej ogólnie, przy użyciu nieco innego repertuaru znaków: kilka punktów kodowych reprezentujących jeden znak Unicode lub odwrotnie (patrz np. strona kodowa 437 ). Niektóre źródła określają kodowanie jako starsze tylko dlatego, że poprzedzał Unicode. Wszystkie strony kodowe systemu Windows są zwykle określane jako starsze, zarówno dlatego, że są starsze niż Unicode, jak i dlatego, że nie są w stanie reprezentować wszystkich 221 możliwych punktów kodowych Unicode.

Tłumaczenie kodowania znaków

W wyniku stosowania wielu metod kodowania znaków (i potrzeby wstecznej kompatybilności z danymi archiwalnymi) opracowano wiele programów komputerowych do tłumaczenia danych między schematami kodowania jako formy transkodowania danych . Niektóre z nich są cytowane poniżej.

Wieloplatformowy :

Uniksopodobne :

  • cmv – proste narzędzie do transkodowania nazw plików.
  • convmv – konwertuje nazwę pliku z jednego kodowania na inne.
  • cstocs – konwertuje zawartość pliku z jednego kodowania na inne dla języków czeskiego i słowackiego.
  • enca – analizuje kodowania dla podanych plików tekstowych.
  • recode – konwertuje zawartość pliku z jednego kodowania na inne.
  • utrac – konwertuje zawartość pliku z jednego kodowania na inne.

Okna :

  • Encoding.Convert — interfejs API platformy .NET
  • MultiByteToWideChar/WideCharToMultiByte – do konwersji z ANSI na Unicode i Unicode na ANSI
  • cscvt – narzędzie do konwersji zestawu znaków
  • enca – analizuje kodowania dla podanych plików tekstowych.

Zobacz też

Wspólne kodowanie znaków

Dalsza lektura

Linki zewnętrzne