fbpx

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.

ASCII - cała tablica
Rysunek 1. Tabela kodów ASCII.
ASCII - cała tablica
Rysunek 2. Podział tablicy znaków na sektory.

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.

ASCII - znaki drukowalne
Rysunek 3. 33 bity przeznaczone na znaki sterujące.
Rysunek 4. Znaki sterujące — układ w tabeli znaków

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.

ASCII - znaki drukowalne
Rysunek 5. 95 bitów przeznaczonych na znaki drukowalne.
ASCII - znaki drukowalne
Rysunek 6. Znaki drukowalne — układ w tabeli znaków

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!

Autor

Programista .NET i Python. Autor książki "Programistą być".

14 komentarzy

  1. Pingback: #25. Szyfr Cezara | Mateusz Rus - Programowanie z pasją

    • Cześć Asiu,

      bardzo dziękuję za miły komentarz! Planuję dwa tego typu artykuły w najbliższym czasie.

      Pozdrawiam, Mateusz Rus.

  2. 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ą :-).

  3. 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.

Napisz komentarz

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.

SPRAWDŹ POLECANĄ KSIĄŻKĘ. Najlepsze materiały do nauki programowania!

X