Kod ASCII przypisuje 128 znakom liczby od 0 do 127 i do dziś wyznacza pierwsze 128 pozycji Unicode oraz jednobajtowe znaki w UTF-8. Dlatego wielka litera A ma kod 65 w Pythonie, JavaScripcie i C++, a plik zawierający wyłącznie znaki ASCII ma identyczne bajty w ASCII i w UTF-8. Polskich liter w ASCII nie ma. Litera “ą” zajmuje jeden bajt w starych stronach kodowych i dwa w UTF-8, a różne wartości tego bajtu tłumaczą krzaki w źle otwartym pliku.
Kod ASCII: co to jest
ASCII (American Standard Code for Information Interchange) to 7-bitowy kod znaków: każdemu z 128 znaków przypisuje liczbę od 0 do 127. Siedem bitów daje dokładnie 2 do potęgi 7, czyli 128 kombinacji. W tabeli są wielkie i małe litery alfabetu angielskiego, cyfry, znaki interpunkcyjne, spacja oraz 33 znaki sterujące, które niczego nie wyświetlają.
Najłatwiej dostępny dokument z pełną tabelą ASCII to RFC 20 z 16 października 1969 roku. Vint Cerf zaproponował w nim 7-bitowe ASCII do wymiany danych między komputerami w sieci, zapisane w 8-bitowym bajcie, którego najstarszy bit zawsze wynosi 0. RFC 20 reprodukuje tabelę z normy USAS X3.4-1968. Dokument wspomina też oznaczenie “ASCII 63” dla wcześniejszego wydania normy z 1963 roku.
Ten zerowy ósmy bit ma znaczenie do dziś. Microsoft w dokumentacji stron kodowych pisze, że wartości od 0x00 do 0x7F we wszystkich stronach kodowych Windows i DOS odpowiadają 7-bitowemu ASCII. Wszystko powyżej 127 każdy system i każdy język rozwiązywał po swojemu.
Tabela ASCII 0-127 z kodami dziesiętnymi, hex i binarnymi
Tablica kodów ASCII ma 128 pozycji: 33 znaki sterujące (0-31 i 127) oraz 95 znaków drukowalnych (32-126), wliczając spację. Grafika pokazuje całą tabelę w układzie z RFC 20, a pod nią są te same kody w tabelach tekstowych do skopiowania.

Znaki sterujące ASCII: kody 0-31 i 127
Znaki sterujące nie mają obrazu na ekranie. Pierwotnie sterowały dalekopisem albo transmisją: przesuwały papier, dzwoniły, oznaczały początek i koniec tekstu. Skróty i angielskie nazwy pochodzą z RFC 20, polskie opisy są nasze. RFC 20 zaznacza, że DEL w ścisłym sensie nie jest znakiem sterującym, ale tradycyjnie wymienia się go razem z nimi.
| Dziesiętnie | Hex | Binarnie (7 bitów) | Skrót | Nazwa w RFC 20 | Po polsku |
|---|---|---|---|---|---|
| 0 | 00 | 0000000 | NUL | Null | znak pusty |
| 1 | 01 | 0000001 | SOH | Start of Heading | początek nagłówka |
| 2 | 02 | 0000010 | STX | Start of Text | początek tekstu |
| 3 | 03 | 0000011 | ETX | End of Text | koniec tekstu |
| 4 | 04 | 0000100 | EOT | End of Transmission | koniec transmisji |
| 5 | 05 | 0000101 | ENQ | Enquiry | zapytanie |
| 6 | 06 | 0000110 | ACK | Acknowledge | potwierdzenie |
| 7 | 07 | 0000111 | BEL | Bell | dzwonek |
| 8 | 08 | 0001000 | BS | Backspace | cofnięcie o znak |
| 9 | 09 | 0001001 | HT | Horizontal Tabulation | tabulator poziomy |
| 10 | 0A | 0001010 | LF | Line Feed | nowa linia |
| 11 | 0B | 0001011 | VT | Vertical Tabulation | tabulator pionowy |
| 12 | 0C | 0001100 | FF | Form Feed | nowa strona |
| 13 | 0D | 0001101 | CR | Carriage Return | powrót karetki |
| 14 | 0E | 0001110 | SO | Shift Out | wyjście z zestawu |
| 15 | 0F | 0001111 | SI | Shift In | powrót do zestawu |
| 16 | 10 | 0010000 | DLE | Data Link Escape | zmiana znaczenia (łącze) |
| 17 | 11 | 0010001 | DC1 | Device Control 1 | sterowanie urządzeniem 1 |
| 18 | 12 | 0010010 | DC2 | Device Control 2 | sterowanie urządzeniem 2 |
| 19 | 13 | 0010011 | DC3 | Device Control 3 | sterowanie urządzeniem 3 |
| 20 | 14 | 0010100 | DC4 | Device Control 4 (Stop) | sterowanie urządzeniem 4 |
| 21 | 15 | 0010101 | NAK | Negative Acknowledge | potwierdzenie negatywne |
| 22 | 16 | 0010110 | SYN | Synchronous Idle | synchronizacja |
| 23 | 17 | 0010111 | ETB | End of Transmission Block | koniec bloku |
| 24 | 18 | 0011000 | CAN | Cancel | anulowanie |
| 25 | 19 | 0011001 | EM | End of Medium | koniec nośnika |
| 26 | 1A | 0011010 | SUB | Substitute | zastąpienie |
| 27 | 1B | 0011011 | ESC | Escape | escape |
| 28 | 1C | 0011100 | FS | File Separator | separator pliku |
| 29 | 1D | 0011101 | GS | Group Separator | separator grupy |
| 30 | 1E | 0011110 | RS | Record Separator | separator rekordu |
| 31 | 1F | 0011111 | US | Unit Separator | separator jednostki |
| 127 | 7F | 1111111 | DEL | Delete | usunięcie |
Znaki ASCII 32-63: spacja, interpunkcja i cyfry
| Dziesiętnie | Hex | Binarnie | Znak |
|---|---|---|---|
| 32 | 20 | 0100000 | spacja |
| 33 | 21 | 0100001 | ! |
| 34 | 22 | 0100010 | “ |
| 35 | 23 | 0100011 | # |
| 36 | 24 | 0100100 | $ |
| 37 | 25 | 0100101 | % |
| 38 | 26 | 0100110 | & |
| 39 | 27 | 0100111 | ‘ |
| 40 | 28 | 0101000 | ( |
| 41 | 29 | 0101001 | ) |
| 42 | 2A | 0101010 | * |
| 43 | 2B | 0101011 | + |
| 44 | 2C | 0101100 | , |
| 45 | 2D | 0101101 | – |
| 46 | 2E | 0101110 | . |
| 47 | 2F | 0101111 | / |
| 48 | 30 | 0110000 | 0 |
| 49 | 31 | 0110001 | 1 |
| 50 | 32 | 0110010 | 2 |
| 51 | 33 | 0110011 | 3 |
| 52 | 34 | 0110100 | 4 |
| 53 | 35 | 0110101 | 5 |
| 54 | 36 | 0110110 | 6 |
| 55 | 37 | 0110111 | 7 |
| 56 | 38 | 0111000 | 8 |
| 57 | 39 | 0111001 | 9 |
| 58 | 3A | 0111010 | : |
| 59 | 3B | 0111011 | ; |
| 60 | 3C | 0111100 | < |
| 61 | 3D | 0111101 | = |
| 62 | 3E | 0111110 | > |
| 63 | 3F | 0111111 | ? |
Znaki ASCII 64-95: wielkie litery
| Dziesiętnie | Hex | Binarnie | Znak |
|---|---|---|---|
| 64 | 40 | 1000000 | @ |
| 65 | 41 | 1000001 | A |
| 66 | 42 | 1000010 | B |
| 67 | 43 | 1000011 | C |
| 68 | 44 | 1000100 | D |
| 69 | 45 | 1000101 | E |
| 70 | 46 | 1000110 | F |
| 71 | 47 | 1000111 | G |
| 72 | 48 | 1001000 | H |
| 73 | 49 | 1001001 | I |
| 74 | 4A | 1001010 | J |
| 75 | 4B | 1001011 | K |
| 76 | 4C | 1001100 | L |
| 77 | 4D | 1001101 | M |
| 78 | 4E | 1001110 | N |
| 79 | 4F | 1001111 | O |
| 80 | 50 | 1010000 | P |
| 81 | 51 | 1010001 | Q |
| 82 | 52 | 1010010 | R |
| 83 | 53 | 1010011 | S |
| 84 | 54 | 1010100 | T |
| 85 | 55 | 1010101 | U |
| 86 | 56 | 1010110 | V |
| 87 | 57 | 1010111 | W |
| 88 | 58 | 1011000 | X |
| 89 | 59 | 1011001 | Y |
| 90 | 5A | 1011010 | Z |
| 91 | 5B | 1011011 | [ |
| 92 | 5C | 1011100 | \ |
| 93 | 5D | 1011101 | ] |
| 94 | 5E | 1011110 | ^ |
| 95 | 5F | 1011111 | _ |
Znaki ASCII 96-126: małe litery
| Dziesiętnie | Hex | Binarnie | Znak |
|---|---|---|---|
| 96 | 60 | 1100000 | ` |
| 97 | 61 | 1100001 | a |
| 98 | 62 | 1100010 | b |
| 99 | 63 | 1100011 | c |
| 100 | 64 | 1100100 | d |
| 101 | 65 | 1100101 | e |
| 102 | 66 | 1100110 | f |
| 103 | 67 | 1100111 | g |
| 104 | 68 | 1101000 | h |
| 105 | 69 | 1101001 | i |
| 106 | 6A | 1101010 | j |
| 107 | 6B | 1101011 | k |
| 108 | 6C | 1101100 | l |
| 109 | 6D | 1101101 | m |
| 110 | 6E | 1101110 | n |
| 111 | 6F | 1101111 | o |
| 112 | 70 | 1110000 | p |
| 113 | 71 | 1110001 | q |
| 114 | 72 | 1110010 | r |
| 115 | 73 | 1110011 | s |
| 116 | 74 | 1110100 | t |
| 117 | 75 | 1110101 | u |
| 118 | 76 | 1110110 | v |
| 119 | 77 | 1110111 | w |
| 120 | 78 | 1111000 | x |
| 121 | 79 | 1111001 | y |
| 122 | 7A | 1111010 | z |
| 123 | 7B | 1111011 | { |
| 124 | 7C | 1111100 | | |
| 125 | 7D | 1111101 | } |
| 126 | 7E | 1111110 | ~ |
Jak czytać tabelę ASCII: dziesiętnie, szesnastkowo i binarnie
Każdy kod w tabeli to ta sama liczba zapisana na trzy sposoby. Wielka litera A to 65 dziesiętnie, 41 szesnastkowo i 1000001 binarnie. Zapis szesnastkowy jest najwygodniejszy, bo pierwsza cyfra wskazuje kolumnę tabeli, a druga wiersz. RFC 20 podaje przykład litery K: kolumna 4, wiersz 11, czyli bity 1001011, a dziesiętnie 75. Jeśli przeliczanie między systemami sprawia kłopot, krok po kroku pokazujemy je w tekście o systemach liczbowych w programowaniu. Ten sam zapis szesnastkowy spotkasz w kolorach HEX w CSS.
Z tabeli da się odczytać trzy reguły, z których korzystają programiści:
- Wielka i mała litera różnią się o 32. A to 65, a to 97. Binarnie różnią się jednym bitem o wartości 32, więc zmianę wielkości litery da się zrobić operacją XOR z liczbą 32. Na tym samym poziomie bitów działają bramki logiczne.
- Cyfry mają kody od 48 do 57. Znak “7” to 55, więc odejmując 48 od kodu cyfry dostajesz jej wartość liczbową.
- Litery są ułożone alfabetycznie. Porównanie kodów porządkuje słowa, ale tylko w obrębie tej samej wielkości liter: każda wielka litera ma mniejszy kod niż każda mała.
Pierwsza Misja AI · Kodożercy
AI zmienia rynek pracy. Zacznij rozumieć, o co chodzi.
Kurs Pierwsza Misja AI to najkrótszy kurs, po którym naprawdę rozumiesz AI, a na koniec możesz to pokazać certyfikatem. Fabuła w konwencji science fiction i gamifikacja sprawiają, że nie nudzisz się ani minuty.
Dołącz do kursantów →
Znaki sterujące ASCII, które spotkasz do dziś
Większość znaków sterujących wyszła z użycia razem z dalekopisami, ale niektóre nadal regularnie występują w plikach tekstowych. Najważniejsze są dwa: LF (10, nowa linia) i CR (13, powrót karetki). Według dokumentacji Gita Windows zapisuje koniec linii jako parę CR i LF, a macOS i Linux używają samego LF. To dlatego ten sam plik potrafi pokazać w Gicie zmianę w każdej linii, choć nikt nie zmienił w nim ani słowa. Parę CR LF jako koniec wiersza wymagają też protokoły internetowe, na przykład HTTP/1.1 (RFC 9112).
Pozostałe znaki sterujące, które warto znać:
- HT (9) to tabulator, czyli znak wstawiany klawiszem Tab.
- NUL (0) to bajt z samymi zerami. RFC 20 opisuje go jako znak wypełnienia.
- BEL (7) według RFC 20 wzywa uwagę człowieka, na przykład dźwiękiem.
- ESC (27) według RFC 20 zmienia znaczenie kilku następnych znaków. Tak zaczynają się sekwencje sterujące.
- DEL (127) ma same jedynki (1111111). RFC 20 opisuje go jako znak do “wymazywania” błędnych znaków na taśmie perforowanej.
Rozszerzone ASCII i polskie znaki: strony kodowe
Rozszerzone ASCII to potoczna nazwa rodziny stron kodowych, które wykorzystują ósmy bit, czyli kody 128-255. Każda strona kodowa obsadza je innymi znakami. Microsoft dzieli je na strony “ANSI” używane w Windows i strony OEM, które pochodzą z DOS i nadal działają w konsoli. Dla języka polskiego liczą się trzy:
| Kodowanie | Identyfikator Microsoftu | Opis według Microsoftu | Bajt litery “ą” |
|---|---|---|---|
| Windows-1250 | 1250 | strona ANSI dla Europy Środkowej (Windows) | B9 (185) |
| ISO-8859-2 | 28592 | norma ISO 8859-2 dla Europy Środkowej | B1 (177) |
| CP852 | 852 | strona OEM Latin 2 (DOS) | A5 (165) |
| UTF-8 | 65001 | Unicode (UTF-8) | C4 85 (196 133) |
Wartości bajtów policzyliśmy w Pythonie i zgadzają się z tabelami mapowań Windows-1250 i ISO-8859-2 publikowanymi przez Unicode. Windows-1250 i ISO-8859-2 zapisują większość polskich liter tak samo. Różnią się tylko przy sześciu: ą, ś, ź i ich wielkich odpowiednikach Ą, Ś, Ź.
Skąd się biorą krzaki w polskich znakach
Krzaki pojawiają się, gdy program czyta bajty według innej strony kodowej niż ta, w której plik zapisano. Same bajty są poprawne, zawodzi ich interpretacja. Ten sam tekst w trzech kodowaniach ma różną długość: “Zażółć gęślą jaźń” zajmuje 26 bajtów w UTF-8 i 17 w Windows-1250 oraz ISO-8859-2.

Trzy typowe przypadki wyglądają tak (wyniki z Pythona 3.14):
- Plik w UTF-8 otwarty jako Windows-1250. Każda polska litera to w UTF-8 dwa bajty, więc w tym przykładzie każda zamienia się w dwa obce znaki: “Zażółć” daje “Zażółć”. Tak wygląda na przykład plik CSV zapisany w UTF-8 i otwarty w programie, który zakłada Windows-1250.
- Plik w ISO-8859-2 otwarty jako Windows-1250. Psują się tylko ą, ś i ź: “gęślą jaźń” zmienia się w “gę¶l± jaĽń”.
- Plik w Windows-1250 otwarty jako UTF-8. Bajty polskich liter nie tworzą poprawnej sekwencji UTF-8, więc program wstawia znak zastępczy �.
Rozwiązanie zawsze jest to samo: otworzyć plik ze wskazaniem właściwego kodowania, a zapisywać go w UTF-8. Python od wersji 3.15 domyślnie używa UTF-8 przy otwieraniu plików (PEP 686), co opisaliśmy w tekście o Pythonie 3.15 i polskich znakach.
Kody Alt w Windows
Microsoft w instrukcji wstawiania znaków opisuje tę metodę tak:
- Włącz NUM LOCK, jeśli klawiatura tego wymaga.
- Przytrzymaj klawisz Alt.
- Wpisz kod znaku na klawiaturze numerycznej, nie w górnym rzędzie cyfr. Przykład z tej strony: Alt+0176 wstawia znak stopnia °.
Na liście Microsoftu znak « występuje przy dwóch kodach: Alt+0171 i Alt+174. Dokument nie wyjaśnia przyczyny tej różnicy, więc przy wpisywaniu trzymaj się dokładnie kodu z listy. W Wordzie działa też druga metoda: wpisujesz szesnastkowy kod Unicode i naciskasz Alt+X, na przykład 0024 i Alt+X daje znak $. Więcej skrótów do codziennej pracy zebraliśmy w artykule o skrótach klawiszowych Windows i Mac.
Unicode i UTF-8: co zastąpiło ASCII
Unicode to wspólna tabela znaków dla pism całego świata. Każdy znak ma w niej numer, czyli punkt kodowy zapisywany jako U+ i liczba szesnastkowa. Pierwsze 128 punktów kodowych, blok Basic Latin od U+0000 do U+007F, to dokładnie ASCII. Litera “ą” ma numer U+0105 i leży w bloku Latin Extended-A. Aktualna wersja standardu według bazy znaków Unicode to 18.0.
UTF-8 to sposób zapisania punktów kodowych w bajtach. Według RFC 3629 znak z zakresu U+0000-U+007F zajmuje jeden bajt w postaci 0xxxxxxx, czyli dokładnie bajt ASCII. Znaki od U+0080 do U+07FF zajmują dwa bajty, a od U+0800 do U+FFFF trzy. Wyższe punkty kodowe, na przykład emoji, zajmują cztery. Dlatego plik z samym tekstem ASCII jest jednocześnie poprawnym plikiem UTF-8, a polskie litery zajmują w nim po dwa bajty.

Jak sprawdzić kod ASCII znaku w Pythonie, JavaScripcie i C++
Każdy z tych języków ma prosty sposób na zamianę znaku na kod i z powrotem. Poniższe przykłady uruchomiliśmy, a wyniki są skopiowane z konsoli.
Python: ord() i chr()
Funkcja ord() zwraca numer znaku w Unicode, a chr() działa odwrotnie. Dla znaków z ASCII numer Unicode jest tym samym co kod ASCII. Metoda encode() pokazuje bajty w wybranym kodowaniu.
print(ord("A"))
print(chr(97))
print(ord("ą"))
print(hex(ord("ą")))
print("ą".encode("utf-8"))
print("ą".encode("cp1250"))
print("ą".encode("iso-8859-2"))
Wynik (Python 3.14.3):
65
a
261
0x105
b'\xc4\x85'
b'\xb9'
b'\xb1'
JavaScript: charCodeAt() i String.fromCharCode()
Metoda charCodeAt() według dokumentacji MDN zwraca jednostkę kodu UTF-16, czyli liczbę od 0 do 65535. Dla znaków ASCII to ten sam kod. Przy emoji trzeba użyć codePointAt(), bo emoji składa się z dwóch jednostek UTF-16.
console.log("A".charCodeAt(0));
console.log(String.fromCharCode(97));
console.log("ą".charCodeAt(0));
console.log("😀".length, "😀".charCodeAt(0), "😀".codePointAt(0));
console.log(new TextEncoder().encode("ą"));
Wynik (Node.js 22.11):
65
a
261
2 55357 128512
Uint8Array(2) [ 196, 133 ]
C++: rzutowanie char na int
W C++ znak typu char jest małą liczbą, więc kod znaku dostajesz rzutowaniem na int, a znak z kodu rzutowaniem na char.
#include <iostream>
int main() {
char litera = 'A';
std::cout << litera << " = " << static_cast<int>(litera) << '\n';
int kod = 97;
std::cout << kod << " = " << static_cast<char>(kod) << '\n';
std::cout << 'a' - 'A' << '\n';
return 0;
}
Wynik (g++ 14.4):
A = 65
97 = a
32
W UTF-8 polska litera zajmuje więcej niż jeden element typu char. Przy pliku źródłowym zapisanym w UTF-8 napis “ą” ma dwa bajty:
#include <iostream>
#include <string>
int main() {
std::string s = "ą";
std::cout << s.size() << '\n';
for (unsigned char b : s) {
std::cout << static_cast<int>(b) << ' ';
}
std::cout << '\n';
return 0;
}
Wynik (g++ 14.4):
2
196 133
Najczęstsze pytania o ASCII
Ile znaków ma kod ASCII?
128, o kodach od 0 do 127. Drukowalnych jest 95 (32-126, razem ze spacją), a 33 to znaki sterujące (0-31 i 127).
Czy ASCII to 8 bitów?
Nie. ASCII to kod 7-bitowy. W komputerze zapisuje się go w 8-bitowym bajcie z najstarszym bitem równym 0. Kody 128-255 należą do różnych stron kodowych, nazywanych potocznie rozszerzonym ASCII.
Czy polskie znaki są w ASCII?
Nie. ASCII zawiera tylko litery alfabetu angielskiego. Polskie litery zapisuje się w stronach kodowych Windows-1250, ISO-8859-2 albo CP852, a dziś najczęściej w UTF-8, gdzie każda zajmuje dwa bajty.
Czym różni się ASCII od UTF-8?
ASCII to tabela 128 znaków zapisywanych w jednym bajcie. UTF-8 zapisuje wszystkie znaki Unicode w 1-4 bajtach, a pierwsze 128 zapisuje dokładnie tak jak ASCII. Każdy tekst w ASCII jest więc poprawnym tekstem UTF-8, ale nie odwrotnie.
Co to jest ASCII art?
To obrazki złożone wyłącznie ze znaków drukowalnych tabeli ASCII, na przykład liter, kresek i nawiasów. Działają w każdym edytorze tekstu, bo nie potrzebują grafiki ani specjalnych znaków.
Podsumowanie
ASCII to 128 znaków o kodach 0-127, zapisanych na 7 bitach. Tabelę w znanej dziś postaci opisuje RFC 20 z 1969 roku, oparty na normie USAS X3.4-1968. Wielka litera A to 65, mała a to 97, cyfry mają kody 48-57, a spośród 33 znaków sterujących LF i CR wciąż wyznaczają końce linii w plikach. Kody powyżej 127 to już strony kodowe, różne w Windows-1250, ISO-8859-2 i CP852, i stąd krzaki w polskich znakach. Unicode zachował ASCII jako blok U+0000-U+007F, a UTF-8 zapisuje te znaki w jednym bajcie, polskie litery w dwóch. Kod znaku sprawdzisz funkcją ord() w Pythonie, metodą charCodeAt() w JavaScripcie i rzutowaniem na int w C++.
Newsletter · DevstockAcademy & Kodożercy
Bądź na bieżąco ze światem IT, AI i automatyzacji
Co wtorek: newsy z branży, praktyczne tipy i narzędzia które warto znać. Zero spamu.



