Kiedy wstawiam „a” w pliku tekstowym, robi to 2 bajty, ale kiedy wstawiam, powiedzmy „ա”, czyli literę alfabetu ormiańskiego, robi to 3 bajty.
Jaka jest różnica między alfabetami na komputerze?
Dlaczego angielski zajmuje mniej miejsca?
Kiedy wstawiam „a” w pliku tekstowym, robi to 2 bajty, ale kiedy wstawiam, powiedzmy „ա”, czyli literę alfabetu ormiańskiego, robi to 3 bajty.
Jaka jest różnica między alfabetami na komputerze?
Dlaczego angielski zajmuje mniej miejsca?
Odpowiedzi:
Jednym z pierwszych schematów kodowania, które zostaną opracowane do użytku w komputerach głównego nurtu, jest standard ASCII ( American Standard Code for Information Interchange ). Został opracowany w 1960 roku w Stanach Zjednoczonych.
Alfabet angielski używa części alfabetu łacińskiego (na przykład w języku angielskim jest kilka akcentowanych słów). Alfabet składa się z 26 pojedynczych liter, bez uwzględnienia wielkości liter. Musiałyby również istnieć pojedyncze cyfry i znaki interpunkcyjne na każdym schemacie, który udaje, że koduje alfabet angielski.
Lata sześćdziesiąte to także czas, w którym komputery nie miały tyle pamięci, ani miejsca na dysku, jakie mamy teraz. ASCII został opracowany jako standardowa reprezentacja funkcjonalnego alfabetu na wszystkich komputerach amerykańskich. Wówczas decyzja o tym, aby każdy znak ASCII miał długość 8 bitów (1 bajt), została podjęta ze względu na techniczne szczegóły tego czasu (artykuł w Wikipedii wspomina o tym, że perforowana taśma utrzymywała 8 bitów na raz). W rzeczywistości oryginalny schemat ASCII może być przesyłany przy użyciu 7 bitów, a osiem można wykorzystać do kontroli parzystości. Późniejsze zmiany rozszerzyły oryginalny schemat ASCII o kilka znaków akcentowanych, matematycznych i terminalnych.
W związku z ostatnim wzrostem korzystania z komputera na całym świecie coraz więcej osób z różnych języków miało dostęp do komputera. Oznaczało to, że dla każdego języka należało opracować nowe schematy kodowania, niezależnie od innych schematów, które byłyby sprzeczne, gdyby były czytane z różnych terminali językowych.
Unicode powstał jako rozwiązanie istnienia różnych terminali, łącząc wszystkie możliwe znaczące znaki w jeden abstrakcyjny zestaw znaków.
UTF-8 to jeden ze sposobów kodowania zestawu znaków Unicode. Jest to kodowanie o zmiennej szerokości (np. Różne znaki mogą mieć różne rozmiary) i zostało zaprojektowane z myślą o kompatybilności wstecznej z poprzednim schematem ASCII. Jako taki, zestaw znaków ASCII pozostanie duży na jeden bajt, podczas gdy inne znaki będą miały dwa lub więcej bajtów. UTF-16 to kolejny sposób kodowania zestawu znaków Unicode. W porównaniu do UTF-8 znaki są kodowane jako zestaw jednej lub dwóch 16-bitowych jednostek kodu.
Jak stwierdzono w komentarzach, znak „a” zajmuje jeden bajt, podczas gdy „ա” zajmuje dwa bajty, co oznacza kodowanie UTF-8. Dodatkowy bajt w twoim pytaniu wynikał z istnienia znaku nowej linii na końcu (o którym dowiedział się PO).
echo 'ա' > file.txt
to zrobisz lub edytujesz plik za pomocą edytorów, automatycznie dodają po nim nowy wiersz. Jeśli uruchomisz xxd file.txt
, ostatnim bajtem będzie prawdopodobnie 0a
linia lub wiersz.
a
, użyje dwóch bajtów (lub wielokrotności dwóch).
1 bajt to 8 bitów, a zatem może reprezentować do 256 (2 ^ 8) różnych wartości.
W przypadku języków, które wymagają więcej możliwości, proste mapowanie 1 do 1 nie może być utrzymane, więc potrzeba więcej danych do przechowywania znaku.
Zauważ, że ogólnie większość kodowań używa pierwszych 7 bitów (128 wartości) dla znaków ASCII . Pozostawia to 8-ty bit lub 128 więcej wartości dla większej liczby znaków. . . dodaj znaki akcentowane, języki azjatyckie, cyrylicę itp., aby łatwo zrozumieć, dlaczego 1 bajt nie wystarcza do zachowania wszystkich znaków.
W UTF-8 znaki ASCII używają jednego bajtu, inne znaki używają dwóch, trzech lub czterech bajtów.
Ilość bajtów wymagana dla znaku (o którym najwyraźniej chodzi o pytanie) zależy od kodowania znaku. Jeśli używasz kodowania ArmSCII, każda litera armeńska zajmuje tylko jeden bajt. Jednak w dzisiejszych czasach nie jest to dobry wybór.
W kodowaniu przesyłania UTF-8 dla Unicode znaki wymagają innej liczby bajtów. W nim „a” zajmuje tylko jeden bajt (idea dwóch bajtów jest pewnego rodzaju zamieszaniem), „á” zajmuje dwa bajty, a ormiańska litera ayb „ա” również zajmuje dwa bajty. Trzy bajty muszą być pewnego rodzaju zamieszaniem. Dla kontrastu, np. Litera bengalska „অ” zajmuje trzy bajty w UTF-8.
Tłem jest po prostu to, że UTF-8 został zaprojektowany tak, aby był bardzo wydajny dla znaków Ascii, dość wydajny dla systemów pisania w Europie i otoczeniu, a cała reszta jest mniej wydajna. Oznacza to, że podstawowe litery łacińskie (z których w większości składa się tekst angielski), potrzebny jest tylko jeden bajt dla znaku; w przypadku greckiego, cyrylicy, ormiański i kilku innych potrzebne są dwa bajty; cała reszta potrzebuje więcej.
UTF-8 ma (jak wskazano w komentarzu) także użyteczną właściwość, że dane Ascii (reprezentowane jako jednostki 8-bitowe, co było prawie jedynym sposobem od dłuższego czasu), są również w prosty sposób zakodowane w UTF-8.
Kody znaków w latach 60. XX wieku (i znacznie później) były specyficzne dla maszyny. W latach 80. krótko użyłem maszyny DEC 2020, która miała 36 bitów słów oraz 5, 6 i 8 bitów ( IIRC ) na kodowanie znaków. Wcześniej korzystałem z serii IBM 370 z EBCDIC. ASCII z 7 bitami uporządkował, ale dostał bałagan z „stronami kodowymi” IBM PC, używając wszystkich 8 bitów do przedstawienia dodatkowych znaków, takich jak wszelkiego rodzaju rysunki pudełkowe do malowania prymitywnych menu, a później rozszerzenia ASCII, takie jak Latin-1 (8 bitów) kodowania, przy czym pierwsze 7 bitów jak ASCII, a druga połowa dla „bohaterów narodowych” takich ñ
, Ç
czy innych. Prawdopodobnie najbardziej popularne było Latin-1, dostosowane do języka angielskiego i większości języków europejskich przy użyciu znaków łacińskich (i akcenty i warianty).
Pisanie mieszania tekstu, np. Angielskiego i hiszpańskiego, poszło dobrze (wystarczy użyć Latin-1, nadzbiór obu), ale mieszanie wszystkiego, co używało innego kodowania (np. Fragment greckiego lub rosyjskiego, nie mówiąc już o języku azjatyckim, takim jak japoński) było istny koszmar. Najgorsze było to, że rosyjski, a zwłaszcza japoński i chiński, miał kilka popularnych, całkowicie niekompatybilnych kodowań.
Dziś używamy Unicode, który jest spakowany do wydajnych kodowań, takich jak UTF-8, które faworyzują znaki angielskie (co zaskakujące, kodowanie liter angielskich tak się składa, że odpowiada ASCII), przez co wiele znaków nieanglojęzycznych używa dłuższych kodowań.
Plik Windows 8.1 US / angielski z pojedynczym „a” zapisanym za pomocą notatnika.
Plik z pojedynczym „ա” zapisanym w notatniku
Pojedynczy „a” jest kodowany jako pojedynczy bajt w ANSI, w Unicode każdy znak ma zwykle 2 bajty, na początku pliku znajduje się również 2 bajtowy BOM (Bajt Marker). UTF-8 ma 3-bajtowe BOM i znak jednobajtowy.
Dla „ա” ten znak nie istnieje w zestawie znaków ANSI i nie można go zapisać na moim komputerze. Plik Unicode jest taki sam jak poprzednio, a plik UTF-8 jest o 1 bajt większy, ponieważ znak zajmuje 2 bajty.
Jeśli twoje urządzenie pochodzi z innego regionu, możesz mieć zainstalowaną inną stronę kodową OEM, która ma różne glify dla 255 możliwych znaków w zakresie ASCII. Jak wspomniałem @ntoskrnl, strona kodowa OEM dla mojego komputera to Windows-1252, który jest domyślnym językiem angielskim w USA.
Jeśli interesuje Cię sposób przechowywania znaków, możesz przejść do www.unicode.org i rozejrzeć się. U góry strony głównej znajduje się link „Tabele kodów”, który pokazuje wszystkie kody znaków dostępne w standardzie Unicode.
Podsumowując, w Unicode dostępnych jest nieco ponad milion kodów (nie wszystkie są używane). Jeden bajt może pomieścić 256 różnych wartości, więc potrzebujesz trzech bajtów, jeśli chcesz zapisać każdy możliwy kod Unicode.
Zamiast tego Unicode jest zwykle przechowywany w kodowaniu „UTF-8”, który wykorzystuje mniej bajtów dla niektórych znaków i więcej dla innych. Pierwsze 128 wartości kodu jest przechowywanych w jednym bajcie, do pierwszych 2048 wartości kodu jest przechowywanych w dwóch bajtach, do 65536 jest przechowywanych w trzech bajtach, a pozostałe zajmują cztery bajty. Zostało to ustawione tak, aby częściej używane wartości kodu zajmowały mniej miejsca. AZ, az, 0-9 i! @ $% ^ & * () - [} {}; ': "|,. / <>? I niektóre, o których zapomniałem, zajęły jeden bajt; prawie cały angielski, 98% Niemiecki i francuski (tylko zgadywanie) mogą być przechowywane w jednym bajcie na znak, a są to znaki, które są najczęściej używane. Cyrylica, grecki, hebrajski, arabski i niektóre inne używają dwóch bajtów na znak. Języki indyjskie, większość chińska, japońska , Koreański, tajski, mnóstwo symboli matematycznych, można zapisać w trzech bajtach na znak. Rzadkie rzeczy (jeśli kiedykolwiek chcesz pisać tekst w Linear A lub Linear B, Emoji) zajmują cztery bajty.
Kolejnym kodowaniem jest UTF-16. Wszystko, co zajmuje 1, 2 lub 3 bajty w UTF-8, zajmuje dwa bajty w UTF-16. Jest to zaleta, jeśli masz tekst chiński lub japoński z niewielką liczbą znaków łacińskich.
O przyczynach projektu UTF-8: Ma kilka zalet w porównaniu z innymi projektami. Oni są:
Zgodność ze znakami US-ASCII
Rozsądna zwartość
Samosynchronizacja: Oznacza to, że jeśli otrzymasz część sekwencji bajtów, które są znakami w kodowaniu UTF-8, możesz dowiedzieć się, gdzie zaczyna się znak. W niektórych kodowaniach zarówno xy, jak i yx mogą być prawidłowymi kodowaniami znaków, więc jeśli otrzymasz część sekwencji ... xyxyxyxyxyxy ... nie możesz wiedzieć, jakie masz znaki.
Poprawność sortowania: Jeśli sortujesz ciągi zawierające znaki zakodowane w UTF-8 według ich wartości bajtów, są one automatycznie sortowane poprawnie zgodnie z ich wartościami Unicode.
Zgodny z kodem jednobajtowym: większość kodu, który zakłada wartości jednobajtowe, działa automatycznie poprawnie ze znakami zakodowanymi w UTF-8.
Plus niezależnie od powodów, o których zapomniałem.