Każda osoba, która zetknęła się z informatyką, słyszała o magicznym skrócie ASCII. Postanowiłem zmierzyć się z tematem i zapoznać ze szczegółami jednego z pierwszych standardów kodowania.
- Zastanawiałeś się kiedyś, jak dokładnie wygląda reprezentacja binarna znaków wpisywanych z klawiatury?
- Chcesz poznać historię jednego z pierwszych systemów kodowania znaków?
- Dlaczego oraz w jaki sposób ASCII mimo ponad 50 lat obecności w świecie IT jest nadal używany?
- W jaki sposób języki programowania radzą sobie z zamianą znaków ASCII na kod dziesiętny?
- Jak można pisać znaki drukowalne w notatniku za pomocą liczb?
- W jaki sposób binarnie prezentowane są liczby w kodowaniu ASCII?
Jeżeli ciekawią Cię odpowiedzi na powyższe pytania, to zapraszam do przeczytania artykułu!
Zatrzymaj się!
Książki to obowiązkowa pozycja dla każdego zainteresowanego programowaniem!
Jest to zdecydowanie jedno z najlepszych źródeł do nauki programowania! Zyskasz przewagę w branży IT i osiągniesz dużo jako deweloper.
Jak to się zaczęło?
ASCII to jeden z pierwszych systemów kodowania znaków i dla niektórych to historia, ale warto o niej trochę więcej wiedzieć.
Skrót ASCII to inaczej American Standard Code for Information Interchange. Standard wywodzi się od kodu używanego w dalekopisach, który został stworzony w latach 80 XIX wieku. Twórcą był Émile Baudot. Na początku XX wieku kod Baudota został zmodyfikowany przez Donalda Murray’a (kod Baudot-Murray). Kolejne modyfikacje wykonał Western Union. W późniejszych latach komitet X3 do pierwotnych znaków zaplanował dodać znaki kontrolne, przez co wymagane było już użycie większej ilości bitów.
Wszystkie te aspekty spowodowały, że jednym z głównych założeń, jakie postawili sobie twórcy, było zapisywanie pojedynczego znaku na 7 bitach.
W rezultacie dzięki kompatybilności wstecz jego pierwsze zastosowanie miało miejsce w usługach telekomunikacyjnych firmy BELL oraz w teleprinterach TWX.
Pojedynczy znak w kodzie ASCII zawiera 7 bitów.
Początki prac
Prace nad ASCII rozpoczęto 6 października 1960 roku w amerykańskiej instytucji normalizującej ANSI (American National Standards Institute) inaczej zwanej komitetem X3. Prace zakończono w roku 1963 i ukazała się pierwsza wersja standardu pod nazwą X3.4-1963.
Pierwsza wersja zawierała 33 znaki specjalne oraz 95 znaków drukowalnych opartych na alfabecie angielskim. Do znaków drukowalnych należą cyfry od 0 do 9, małe i duże litery od A do Z oraz znaki interpunkcyjne.
Wersja ta nie cieszyła się zbyt dużą popularnością, chociażby ze względu na odrzucenie standardu przez firmę IBM, która nadawała w tamtym czasie tempo rozwojowi branży.
Kolejną wersją była wersja ASCII-1965, która finalnie nie ukazała się szerszej publiczności i zawierała jedynie kosmetyczne zmiany względem wersji z roku 1963. ASCII-1967 (USAS X3.4-1967) to pierwsza zmieniona i wdrożona zmiana standardu, która przypomina wersję ASCII, jaką znamy dziś. Pozostałe wersje nie różniły się znacząco od wersji z 1967 roku. Łącznie standard ASCII zmieniany był sześć razy, z czego zmiana z roku 1965 nie została oficjalnie opublikowana.
Wszystkie standardy
Podsumowując poniżej wszystkie wersje standardów ASCII:
- ASA X3.4-1963
- ASA X3.4-1965*
- USAS X3.4-1967
- USAS X3.4-1968
- ANSI X3.4-1977
- ANSI X3.4-1986
Główne różnice między wersjami ASA X3.4-1963 i USAS X3.4-1967 zamykały się w trzech kwestiach. Po pierwsze usunięto znak kontrolny RU. Po drugie wprowadzono znaki drukowalne (nawiasy klamrowe i kreskę pionową). Ponadto dokonano kosmetycznej zmiany nazwy kodu SOM na SOH.
Jednym z przełomów i powodów, dla których ASCII zyskał mocną pozycję na rynku, było oświadczenie prezydenta USA Lyndona Johnsona, który nakazał użycie standardu we wszystkich komputerach używanych przez rząd Stanów Zjednoczonych.
ASCII — założenia
Przede wszystkim założeniem podstawowym ASCII jest kodowanie na 7 bitach. Postanowiono, że tablica znaków zostanie podzielona na osiem tak zwanych patyków, gdzie w każdym patyku będzie znajdowało się 16 znaków.
Tablica znaków ASCII podzielona jest na 8 patyków po 16 znaków każdy.
Pierwsze dwa patyki, czyli wiersz 0x, 1x oraz ostatni znak z patyka 7x odpowiadają znakom sterującym. W związku z tym patyki od 2x do 7x to znaki drukowalne, które widoczne są bezpośrednio na urządzeniach wyjściowych.
Tablica znaków mogła zostać oparta na 8 bitach, jednak w latach 60 każdy bit miał znaczenie i w tamtym czasie nie było możliwości, by marnować bardzo cenne miejsce w pamięci. Przesyłanie danych również było bardzo kosztowną czynnością i to był drugi argument, by pozostać przy 7-bitowej wersji.
Przede wszystkim patrząc na rysunek 2 można podzielić tablicę na następujące sektory:
- GRANATOWY — znaki sterujące
- BŁĘKITNY — znaki interpunkcyjne
- POMARAŃCZOWY — cyfry
- CIEMNY SZARY — duże litery
- SZARY — małe litery
- ZIELONY — symbole
ASCII — Znaki sterujące
Po pierwsze — znaki sterujące (kontrolne), które zajmują pierwsze 32 miejsca — numery od 0 do 31 (szesnastkowo 0x00 — 0x1F) oraz ostatni bit na znak DEL — numer 127 (szesnastkowo 0x7F) w tabeli znaków.
We wcześniejszych wersjach systemów operacyjnych nagminnym problemem ze znakami sterującymi był znak nowej linii (CRLF) w pliku tekstowym. Niektóre systemy wymagały połączenia dwóch znaków sterujących (10 i 13) — inne zaś nie. W związku z tym powodowało to problem z wyświetleniem poprawnie pliku pisanego na jednej maszynie, a odczytywanego na innej. Wydaje się, że aktualnie problem ten jest marginalny i zasadniczo nie występuje.
Nazwa „znaki sterujące” wzięła się z tego, że pierwotnie pierwsze 32 znaki miały służyć do obsługi (sterowania) urządzeniami takimi jak drukarki, modemy czy terminale. Dla przykładu znak numer 10 miał za zadanie przesunąć papier w urządzeniach drukujących (w kolejnych wersjach zmienił swoje przeznaczenie, o czym niżej).
W związku z tym w późniejszym czasie znaki sterujące nabrały znaczenia w rozbudowanych edytorach tekstu. Na przykład znak cofnięcia karetki o jeden (Backspace) lub znak (Esc) pozwalający wyjść z kontekstu lub zamknąć okno.
Podsumowując — ciekawostką jest znak 7, czyli dzwonek, który został dodany ze względu na urządzenie o nazwie Teletype Model 33 ASR. Teleprinter to urządzenie, które było połączeniem drukarki z maszyną do pisania. Zawierało wbudowany dzwonek, który był uruchamiany w momencie, gdy następował koniec karty drukowanej.
ASCII — Znaki drukowalne
Po drugie — znaki drukowalne. Jak już wcześniej wspomniałem, znaki widoczne na ekranach monitorów zajmują w tablicy ASCII 95 miejsc. Dzielą się na cyfry, litery małe i duże, symbole oraz znaki interpunkcyjne.
Podczas debat nad kodowaniem bardzo często kwestią sporną jest niewidoczna przerwa między znakami, zwana popularnie Spacją. Często mylnie klasyfikowana jest jako znak sterujący, jednak w oficjalnych dokumentach standaryzacyjnych jest on zapisany jako pierwszy znak drukowalny, mimo iż nie jest widoczny.
Dodatkowo warto odnotować, że wcześniejsze wersje ASCII używały strzałki w górę zamiast znaku karetki i strzałki w lewo zamiast znaku podkreślenia.
Ponadto patrząc wstecz nie widać zbyt wielu zmian w tablicy dotyczących znaków drukowalnych. Jednym z bardziej znaczących była migracja znaku @, gdzie w 1963 roku znak ten był na 64 miejscu, następnie w roku 1965 trafił w miejsce znaku ’ (odwrotna kreska, inaczej akcent grave) na pozycję 97, by po dwóch latach wrócić na stare miejsce i pozostać na nim aż do dziś.
Pokodujmy — proste implementacje
Postanowiłem zmierzyć się z bardzo prostą interpretacją wartości znaków ASCII w kodzie. Na początek język C++ i metoda main, która po otrzymaniu znaku z klawiatury poda jego interpretację dziesiętną.
C++
Język C++ daje możliwość zamiany znaku w zmiennej typu char na liczbę za pomocą prostego rzutowania do typu int. Przykładowo dla małej litery a wprowadzonej z klawiatury na konsoli wyświetli się wartość 97. Dla spacji będzie to wartość 32.
#include <iostream>
using namespace std;
int main () {
char c;
cout << "Podaj cyfrę, znak interpunkcyjny lub małą albo dużą literę: ";
cin >> c;
cout << "Wartość dziesiętna w tablicy ASCII to: ";
cout << static_cast<int>(c);
}
C#
Bardzo podobnie sytuacja ma się w przypadku języka C#. Poniżej fragment kodu, który analogicznie jak powyżej pobiera od użytkownika jeden znak z klawiatury i za pomocą parsowania do typu int pokazuje na ekranie wartość dziesiętną kodu ASCII.
using System;
namespace AsciiDziesietnie
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Podaj cyfrę, znak interpunkcyjny, małą albo dużą literę:");
char c = char.Parse(Console.ReadLine());
int AsciiValue = Convert.ToInt32(c);
Console.WriteLine("Wartość dziesiętna to: " + AsciiValue.ToString());
Console.ReadLine();
}
}
}
Czy wiesz, że…
Wbrew pozorom standard ASCII może kryć w sobie ciekawe zagadnienia. Jedną z ciekawostek jest ułożenie w tablicy znaków liter — chodzi o różnicę binarną między literami małymi i dużymi. Na powyższych rysunków widać, że różnica między wielkością liter wynosi dokładnie 1 bit — chodzi dokładnie o szósty bit.
Na przykład litera D (mała litera reprezentowana jest binarnie jako 01100100, a wielka litera to 01000100).
Ponadto ciekawą zagrywkę zastosowano również w przypadku cyfr. Rozpoczynają się one od 3 bitów równych 011, a następne cztery kolejne bity to ich reprezentacja binarna (i tak dla 4 mamy 0110100, dla 7 dla przykładu 0110111).
Jednym z ciekawych sposób jest wypisywanie znaków z klawiatury za pomocą skrótu ALT + kod dziesiętny z tablicy znaków. Na przykład, aby wypisać małą literę a można wcisnąć klawisz ALT i wpisać na klawiaturze numerycznej 97 (po puszczeniu przycisku ALT pojawi się litera). Tak można postąpić z każdym znakiem drukowalnym.
Warto wspomnieć, że amerykański standard miał swój międzynarodowy odpowiednik o nazwie ISO 646 (CCITT International Alphabet No. 5). Publikacja miała miejsce dwa lata po wydaniu pierwszej wersji ASCII.
Pierwsze podsumowanie
Pierwszy wpis i pierwsze podsumowanie! Nie ukrywam, że było to ciekawe doświadczenie. Starałem się w miarę możliwości rzetelnie i przejrzyście omówić szczegóły dotyczące standardu ASCII. Materiału do analizy jest bardzo wiele i prawdopodobnie wynika to z faktu, że ASCII jest kompatybilne z innymi standardami kodowania takimi jak UTF-8.
Wszystkie materiały, z którymi zapoznałem się w ramach zagadnienia, znajdują się w sekcji Źródła. Dzięki temu można zapoznać się z tematem bardziej szczegółowo. Niech podawanie źródeł na tym blogu będzie standardem! Zapraszam do następnego artykułu dotyczącego podstawowych informacji na temat Blockchain. Więcej po linkem.
Źródła
https://web.archive.org/web/20160613145224/http://www.aivosto.com/vbtips/charsets-7bit.html#body https://web.archive.org/web/20160608104936/http://www.aivosto.com/vbtips/control-characters.html http://www.quadibloc.com/comp/kybint.htm https://textfiles.meulie.net/bitsaved/Books/Mackenzie_CodedCharSets.pdf http://edition.cnn.com/TECH/computing/9907/06/1963.idg/ https://worldpowersystems.com/ARCHIVE/codes/#ASCII-1967 http://www.baudot.net/docs/smith--teletype-codes.pdf https://www.aivosto.com/articles/charsets-7bit.html#body https://web.archive.org/web/20100116001012/http://homepages.cwi.nl/~dik/english/codes/stand.html#ascii https://worldpowersystems.com/ARCHIVE/codes/X3.4-1963/index.html http://www.baudot.net/docs/smith--teletype-codes.pdf http://www.baudot.net/docs/slayton--tty-museum.pdf
Newsletter
Nie przegap i dołącz już dziś do 842 osób będących w tym Newsletter! Otrzymuj co niedzielę o godzinie 20 listę kilku ciekawych tematów, które miałem okazję obserwować w mijającym tygodniu.
Tematy będą głównie techniczne, ale czasami pojawi się coś, co może wprowadzi Cię w stan zadumy i zmusi do dyskusji w szerszym gronie. Zero spamu!
14 komentarzy
do pizdy nie polecam
Pingback: #25. Szyfr Cezara | Mateusz Rus - Programowanie z pasją
Bardzo przystępny artykuł! Czekam na kolejne wątki o systemach kodowania znaków!
Cześć Asiu,
bardzo dziękuję za miły komentarz! Planuję dwa tego typu artykuły w najbliższym czasie.
Pozdrawiam, Mateusz Rus.
Fajny artykuł. Nie wiedziałem że ASCII jest najstarszym systemem kodowania w IT. Zastanawiam się jak implementacja użycia ASCII wygląda w Pythonie. Jest też coś takiego jak ASCII art ale to chyba jest coś innego :-p.
Dzięki za podzielenie się swoją wiedzą :-).
Dziękuje Mateusz za komentarz. Na temat ASCII Art mam w planach napisać mały artykuł !
Pozdrawiam, Mateusz Rus.
.
Ciekawy artykuł. Mógłbyś też napisać o UTF-8 też ma fajną historię, związaną z twórcą UNIX-a. I możesz też napisać o kodowaniu ANSI czyli formatowaniu graficznym w terminalu. Też o ANSI art. Takie arty o historii są bardzo fajne.
Bardzo dziękuje za komentarz.
Mam w planach kilka takich artykułów i zapewne niedawno pojawią się. 🙂
+alert(„hello”)+
Fajne artykuł. Polecam!
Dziękuje bardzo!
Pozdrawiam, Mateusz.
> ASCII (…) wywodzi się kodu telegraficznego, który został użyty we wcześniejszych latach 20 i 30 XX wieku
Kod Baudota jest kilkadziesiąt lat starszy niż piszesz:
https://pl.wikipedia.org/wiki/Kod_Baudot
Cześć.
Bardzo ciekawa sugestia, zweryfikuje i wprowadzę poprawki!
Dziękuje?