Kódy pro odstranění redundance, pro zabezpečení proti chybám Demonstrační cvičení 5 INP
Princip kódování, pojmy Tady potřebujeme informaci zabezpečit, utajit apod. zpráva 000 111 000 0 1 0... kodér dekodér Kódová slova 0 1 0 zdrojová abeceda (abeceda zprávy) = {0, 1} kódová abeceda (abeceda kódových slov) = {0, 1} slovo nad danou abecedou 0, 1 (ve zdrojové) 000, 111 (v kódové); pozn. 001, 010, 011, 100, 101, 110 nejsou kódová slova kódovací předpis (např. 0 000, 1 111 v kódu ztrojení bitů)
O kódování Obecně je kódování předpis, který každému prvku konečné množiny A přiřazuje právě jedno slovo z konečné množiny B. Stručněji, kódování je zobrazení K: A B*. Pojem slova v množině B znamená konečnou (a neprázdnou posloupnost) prvků této množiny. Množinu všech kódových slov označujeme B*. Množina A se nazývá zdrojová abeceda a její prvky zdrojové znaky, množina B se nazývá kódová abeceda a její prvky kódové znaky. Nejdůležitější je případ binárního kódování, které má dva kódové znaky, B={0, 1}. Množinu všech kódových slov K(a) pro všechna a A nazýváme kód. Význam mají jen prostá kódování, tj. taková, kdy různým zdrojovým znakům odpovídají vždy různá kódová slova. Prefixem slova b 1 b 2 b k se rozumí každé ze slov b 1, b 1 b 2,, b 1 b 2 b k. Kódování se nazývá prefixové, jestliže je prosté a žádné kódové slovo není prefixem jiného kódového slova. Prefixové kódování je vždy jednoznačně dekódovatelné: pokud známe zprávu K*(a 1 a 2 a m ), potom v ní najdeme nejmenší počet znaků (zleva), které tvoří kódové slovo, a ty jsou kódem znaku a 1. Dekódované znaky umažeme a zase hledáme nejmenší počet znaků tvořících kódové slovo, to je kód znaku a 2, atd. Příklad: prefixový kód 01 neprefixový kód 01 001 011 100 110 1111 1100 Nejkratším n-znakovým kódováním zdrojové abecedy a 1, a 2,, a r s pravděpodobnostmi výskytu p 1, p 2,, p r se rozumí prefixové kódování této abecedy pomocí n znaků, které má nejmenší možnou průměrnou délku slova. Nejkratší kód lze zkonstruovat pomocí Huffmanova algoritmu.
Typy kódů (podle účelu) Pro odstranění redundance Př. Huffmanovo kódování Př. aplikace: komprese obrazu (JPG=kosinová transformace + Huffmanovo kódování, ztrátová komprese; GIF LZW bezeztrátová komprese) Pro zabezpečení proti chybě parita, ztrojení bitu Hammingův kód cyklické kódy, CRC, a další Pro utajení - šifrování princip: zpráva xor klíč = zakódovaná zpráva DES (symetrické šifrování) RSA (asymetrické šifrování)
Huffmanovo kódování (pro odstranění redundance) Lze sestrojit nejkratší možný kód Potřebujeme znát četnosti výskytu jednotlivých kódovaných symbolů Uděláme statistickou analýzu, popř. odhadneme Huffmanův kód - prefixový V INP např. pro instrukce (krátké značky pro nejčastější instrukce, delší pro méně časté) Příklad: Pomocí Huffmanova kódování zakódujte znaky 0-9 vyskytující se s uvedenou četností: Znak: 0 1 2 3 4 5 6 7 8 9 Četnost: 0.2 0.25 0.15 0.08 0.07 0.06 0.05 0.05 0.05 0.04 Poznámka: bez použití Huffmanova kódování potřebujeme 4 bity na znak a to chceme vylepšit.
Algoritmus: (1) sestavíme ohodnocený strom Spojujeme uzly s nejnižším ohodnocením Každým spojením redukujeme počet uzlů o jeden Takto postupujeme až k jedinému uzlu s ohodnocením 1 znak četnost 0 0.2 1 0.25 2 0.15 3 0.08 4 0.07 0.13 0.17 0.32 0.43 0.57 1.00 5 0.06 0.23 6 0.05 0.10 7 0.05 8 0.05 9 0.04 0.09
Algoritmus: (2) uzly systematicky očíslujeme 0 k horním hranám, 1 ke spodním hranám Cestou od vrcholu ke znakům vytvoříme kód kód 00 10 110 1110 0100 0101 0110 0111 11110 11111 znak četnost 0 0.2 1 0.25 2 0.15 3 0.08 4 0.07 5 0.06 6 0.05 7 0.05 8 0.05 9 0.04 0 1 0 1 0 1 0.13 1 0.10 0.09 0 0 1 0.17 0.23 0 0 1 1 0.32 0 1 0.43 0.57 0 1 1.00 Pokud je číslování systematické, je kód prefixový, tj začátek každé značky je unikátní.
Příklad: dekódujte posloupnosti kód 00 10 110 1110 0100 0101 0110 0111 11110 11111 znak četnost 0 0.2 1 0.25 2 0.15 3 0.08 4 0.07 5 0.06 6 0.05 7 0.05 8 0.05 9 0.04 Dekódujte tuto posloupnost 20 bitů: 00 10 00 10 1110 0110 00 00 0 1 0 1 3 6 0 0 Jedná se o 8 znaků. Při použití běžného kódování by bylo třeba 8x4=32bitů! (úspora) Posloupnost 9999 představuje v tomto Huffmanově kódu 4x5=20 jedniček (bitů). Při použití běžného kódování by bylo třeba jen 4x4=16 bitů. Výskyt této posloupnosti je však málo pravděpodobný.
Vlastnosti kódu kód 00 10 110 1110 0100 0101 0110 0111 11110 11111 znak L i f i 0 2 0.2 1 2 0.25 2 3 0.15 3 4 0.08 4 4 0.07 5 4 0.06 6 4 0.05 7 4 0.05 8 5 0.05 9 5 0.04 průměrná délka značky: L p = ΣL i /n = 3.7 (i=0 9) střední dynamická délka značky: L stř = ΣL i *f i = 2*0.2+ +5*0.04 = 3.04 teoretická optimální délka značky: L opt = -Σ f i * log 2 f i = 3.01 Redundance kódu: R = (L stř -L opt )/L stř = 0.98% Pozn.: log 2 x = log 10 x / log 10 2
Kódy pro zabezpečení a opravu Př. Na 8 bitech zprávy (256 inf. kombin.) nelze detekovat chybu. Pokud chceme umět zjišťovat chyby a opravovat je, musíme přidat nějakou redundanci!! Tj., k informačním bitům zprávy vhodně doplníme nějaké bity kontrolní. Separabilní kód - lze oddělit kontrolní a informační bity Na tomto cvičení: parita (redundance 1 bit, počet zabezpečených kombinací je 128, na 8 bitech), ztrojení bitu, Hammingův kód. Cyklické kódy a další - viz speciální kurz na FIT
Def: Hammingova vzdálenost d Nejmenší počet bitů, v nichž se dvojice kódových kombinací liší (počítáno přes všechny možné dvojice) kód d bez zabezpečení 1 SED 2 SEC 3 SEC - DED 4 DEC 5 S/D = simple/double E = error D/C = detection/correction
Příklad SED - sudá parita d=2 vzniká doplněním jednoho bitu ke značce tak, aby počet jedniček byl sudý odhalí chybu v jednom bitu, ale nedokáže určit její pozici (tj. opravit) Příklad: 8b informačních, 1b kontrolní (zabezpečovací) 0110 1010 0 při chybě 0110 00100 => lichý počet 1 => chyba při chybě 0110 00110 => sudý počet 1 => hlásí, že je vše OK, nepozná chybu
Příklad SEC - ztrojení bitu d=3 vzniká ztrojením každého bitu: 0 000, 1 111 při výskytu jedné chyby v trojici dokáže odvodit původní hodnotu z majority Kódové kombinace: 000, 111 Nekódové kombinace: 001, 010, 011, 100, 101, 110 Opravy: (001, 010, 100) 0, (011, 101, 110) 1 Příklad: Zpráva: 0 1 1 0 1 Zakódováno: 000 111 111 000 111 Při chybě: 000 111 101 001 111 se správně opraví na 0 1 1 0 1 Při chybě: 000 100 111 000 111 se chybně opraví na 0 0 1 0 1, tj. nedokáže detekovat dvojchybu
Příklad SEC - Hammingův kód (HK) d = 3 kódové slovo obsahuje navíc kontrolní bity, jejichž umístění je dáno pozicí (indexem i) bitu ve slově pokud je i mocnina 2, je bit kontrolní (C) - jinak je to bit informační (I) kontrolní bity jsou tvořeny pomocí funkce XOR z informačních bitů minimální možná redundance pro SEC Hammingův kód je separovatelný
HK (n, k) n délka kódového slova (v bitech) k počet informačních bitů m počet kontrolních bitů n = 2 m 1 n = m + k HK(7, 4), HK(15, 11) apod. pro větší n je poměr k/n příznivější
HK(7,4) Jak určit informační a kontrolní bity? i binárně Generující matice 1 1 1 1 0 0 0 1 1 0 0 1 1 0 1 0 1 0 1 0 1 I7 I6 I5 C4 I3 C2 C1 7 6 5 4 3 2 1 C4 C2 C1 i Pokud je i mocnina 2, je bit kontrolní (C) - jinak je to bit informační (I)
Hammingův kód (7,4) - kodér I(0) I(1) I(2) I(3) C(1) C(2) I(3) C(4) I(5) I(6) I(7) Generující rovnice (pro výpočet kontrolních bitů): C 1 = I 3 xor I 5 xor I 7 C 2 = I 3 xor I 6 xor I 7 C 4 = I 5 xor I 6 xor I 7 1 1 1 1 0 0 0 1 1 0 0 1 1 0 1 0 1 0 1 0 1 I7 I6 I5 C4 I3 C2 C1 7 6 5 4 3 2 1 i C4 C2 C1
Příklad Zakódujte v HK(7,4): 1001 Kódové slovo: I 7 I 6 I 5 C 4 I 3 C 2 C 1 I 3 = 1, I 5 = 0, I 6 = 0, I 7 = 1 C 1 = I 3 xor I 5 xor I 7 = 1 xor 0 xor 1 = 0 C 2 = I 3 xor I 6 xor I 7 = 1 xor 0 xor 1 = 0 C 4 = I 5 xor I 6 xor I 7 = 0 xor 0 xor 1 = 1 1001 1001100
Hammingův kód (7,4) kodér ve VHDL library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity enchk4to7 is port ( input: in STD_LOGIC_VECTOR (3 downto 0); -- i7 i6 i5 i3 output: out STD_LOGIC_VECTOR (7 downto 1) -- i7 i6 i5 c4 i3 c2 c1 ); end enchk4to7; architecture enchk4to7 of enchk4to7 is begin output(1) <= input(0) xor input(1) xor input(3); -- c1 = i3 xor i5 xor i7 output(2) <= input(0) xor input(2) xor input(3); -- c2 = i3 xor i6 xor i7 output(3) <= input(0); -- i3 = i3 output(4) <= input(1) xor input(2) xor input(3); -- c4 = i5 xor i6 xor i7 output(5) <= input(1); -- i5 = i5 output(6) <= input(2); -- i6 = i6 output(7) <= input(3); -- i7 = i7 end enchk4to7;
HK (7,4) - dekodér a oprava chyby Možné poškození I 7 I 6 I 5 I 3 I 7 I 6 I 5 C 4 I 3 C 2 C 1 I 7 I 6 I 5 C 4 I 3 C 2 C 1 I 7 I 6 I 5 I 3 S je syndrom určující pozici chyby ve slově: I 7 I 6 I 5 C 4 I 3 C 2 C 1 C 1 xor C 1 = C 1 xor I 3 xor I 5 xor I 7 C 2 xor C 2 = C 2 xor I 3 xor I 6 xor I 7 C 4 xor C 4 = C 4 xor I 5 xor I 6 xor I 7 S 1 = C 1 xor I 3 xor I 5 xor I 7 S 2 = C 2 xor I 3 xor I 6 xor I 7 S 4 = C 4 xor I 5 xor I 6 xor I 7 S 1 0 S 2 1 S 4 2 DC 3 4 5 6 7 Vše OK I3 xor I5 xor I6 xor I7 xor I3 I5 I6 I7
Příklad Bylo zakódováno: 1001 1001100 Dekódujte a opravte: (a) Přijaté slovo: 1001100 S 1 = C 1 xor I 3 xor I 5 xor I 7 = 0 xor 1 xor 0 xor 1 = 0 S 2 = C 2 xor I 3 xor I 6 xor I 7 = 0 xor 1 xor 0 xor 1 = 0 S 4 = C 4 xor I 5 xor I 6 xor I 7 = 1 xor 0 xor 0 xor 1 = 0 S = 000 => nedošlo k chybě (b) Přijaté slovo: 1001000 S 1 = C 1 xor I 3 xor I 5 xor I 7 = 0 xor 0 xor 0 xor 1 = 1 S 2 = C 2 xor I 3 xor I 6 xor I 7 = 0 xor 0 xor 0 xor 1 = 1 S 4 = C 4 xor I 5 xor I 6 xor I 7 = 1 xor 0 xor 0 xor 1 = 0 S = 011 = 3 > došlo k chybě na pozici 3, po opravě 1001100 Co se stane při dvojchybě?
HK(7,4) dekodér ve VHDL entita DEC3TO8 library IEEE; use IEEE.std_logic_1164.all; entity dec3to8 is port ( addr: in STD_LOGIC_VECTOR (2 downto 0); err: out STD_LOGIC_VECTOR (7 downto 0) ); end dec3to8; architecture dec3to8 of dec3to8 is begin with addr select err <= "10000000" when "111", "01000000" when "110", "00100000" when "101", "00010000" when "100", "00001000" when "011", "00000100" when "010", "00000010" when "001", "00000001" when others; end dec3to8;
HK (7,4) dekodér - VHDL (1) library IEEE; use IEEE.std_logic_1164.all; entity dechk7to4 is port ( input: in STD_LOGIC_VECTOR (7 downto 1); -- vstupni data correct: out STD_LOGIC_VECTOR (3 downto 0) -- opraveny vystup ); end dechk7to4; architecture dechk7to4 of dechk7to4 is component dec3to8 port ( addr: in STD_LOGIC_VECTOR (2 downto 0); err: out STD_LOGIC_VECTOR (7 downto 0) ); end component; signal s : STD_LOGIC_VECTOR (2 downto 0); -- syndrom signal fromdc : STD_LOGIC_VECTOR (7 downto 0); -- vystup dekoderu
HK (7,4) dekodér -VHDL (2) begin -- s1 = c1 xor i3 xor i5 xor i7 s(0) <= input(1) xor input(3) xor input(5) xor input(7); -- s2 = c2 xor i3 xor i6 xor i7 s(1) <= input(2) xor input(3) xor input(6) xor input(7); -- s4 = c4 xor i5 xor i6 xor i7 s(2) <= input(4) xor input(5) xor input(6) xor input(7); DEC: dec3to8 port map ( addr => s, -- syndrom pripojime na adresove vstupy dekoderu err => fromdc -- vystup dekoderu ); correct(0) <= fromdc(3) xor input(3); -- oprav i3 correct(1) <= fromdc(5) xor input(5); -- oprav i5 correct(2) <= fromdc(6) xor input(6); -- oprav i6 correct(3) <= fromdc(7) xor input(7); -- oprav i7 end dechk7to4;
Rozšířený Hammingův kód (8,4) Stejný jako (7,4), ale je přidán jeden paritní bit pro všech 7 bitů. SEC DED lze detekovat dvojchyby d = 4
Rozšířený HK (8,4) - kodér 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 0 0 1 1 0 0 1 0 1 0 1 0 1 0 I7 I6 I5 C4 I3 C2 C1 C0 7 6 5 4 3 2 1 0 C0 C4 C2 C1 Definujeme kontrolní bit: C 0 = C 1 xor C 2 xor I 3 xor C 4 xor I 5 xor I 6 xor I 7
Rozšířený HK (8,4) - dekodér Definujeme: S 0 = C 0 xor C 1 xor C 2 xor I 3 xor C 4 xor I 5 xor I 6 xor I 7 S 1 S 2 S 4 vypočteme stejně jako v HK(7,4) Definujeme syndrom chyby: S = S 1 or S or S 2 4 (detekce nenuloveho syndromu) S 1 = C 1 xor I 3 xor I 5 xor I 7 S 2 = C 2 xor I 3 xor I 6 xor I 7 S 4 = C 4 xor I 5 xor I 6 xor I 7 Chyby klasifikujeme podle tabulky: S S 0 Význam 0 0 Bez chyby 0 1 Neopravitelná chyba (porucha hlídače, vícenásobná chyba) 1 0 Neopravitelná 2-chyba, 4-chyba, atd. 1 1 Opravitelná 1-chyba
Kód zbytkových tříd (KZT) Převedeme binárníčísla do KZT a tam budeme provádět aritmetické operace. Proč? Protože tyto operace lze v KZT implementovat velmi jednoduše bez přenosů, tj. budou rychlejší než konvenční. Operace: sčítání, odčítání a násobení Nefunguje dělení (nejednoznačný výsledek), jednoduché porovnání Nepolyadická soustava: soustava modulů (prvočísel) c i = (a i op b i ) mod m i
m 1 m 2 m 3 No 2 3 5 0 0 0 0 1 1 1 1 2 0 2 2 3 1 0 3 4 0 1 4 5 1 2 0 6 0 0 1 7 1 1 2 8 0 2 3 9 1 0 4 10 0 1 0 11 1 2 1 12 0 0 2 13 1 1 3 14 0 2 4 15 1 0 0 29 1 2 4 30 0 0 0 Opakuje se 30 = 2*3*5 Zakódování čísel a aritmetické operace 1 0 3 (3) +0 1 4 (4) 1 1 2 bez přenosu! 0 0 1 (6) -1 2 0 (-5) 1 1 1 0 1 4 (4) *1 2 0 (5) 0 2 0 1 0 0 (15) /1 2 0 (5)??? c i = (a i + b i ) mod m i c i = (a i - b i ) mod m i c i = (a i * b i ) mod m i c i (a i / b i ) mod m i
m 1 m 2 m 3 No 2 3 5 0 0 0 0 1 1 1 1 2 0 2 2 3 1 0 3 4 0 1 4 5 1 2 0 6 0 0 1 7 1 1 2 8 0 2 3 9 1 0 4 10 0 1 0 11 1 2 1 12 0 0 2 13 1 1 3 14 0 2 4 15 1 0 0 29 1 2 4 30 0 0 0 Opakuje se 30 = 2*3*5 Obvodová realizace: sčítačka Řád 2 Řád 3 Řád 5 Řád 2 Řád 3 Řád 5 A B + A 2 B 2 C 2 0 0 0 0 1 1 1 0 1 1 1 0 =1 C Řád 2 Řád 3 Řád 5 Řád 2: XOR C 2 = A 2 XOR B 2
m 1 m 2 m 3 No 2 3 5 0 0 0 0 1 1 1 1 2 0 2 2 3 1 0 3 4 0 1 4 5 1 2 0 6 0 0 1 7 1 1 2 8 0 2 3 9 1 0 4 10 0 1 0 11 1 2 1 12 0 0 2 13 1 1 3 14 0 2 4 15 1 0 0 29 1 2 4 30 0 0 0 Opakuje se 30 = 2*3*5 Obvodová realizace: sčítačka (2) A 3 B 3 C 3 0 0 0 0 1 1 0 2 2 1 0 1 1 1 2 1 2 0 2 0 2 2 1 0 2 2 1 Řád 2 Řád 3 Řád 5 Řád 2 Řád 3 Řád 5 A 3 B 3 C 3 ab cd uv 00 00 00 00 01 01 00 10 10 01 00 01 01 01 10 01 10 00 10 00 10 10 01 00 10 10 01 A B + C Řád 3: Řád 2 Řád 3 Řád 5 u = f1(a,b,c,d) v = f2(a,b,c,d) Řád 5: obdobně jako řád 3 -,* obdobně jako +
library IEEE; use IEEE.std_logic_1164.all; entity KZT is port ( -- rad 2 A1 : in std_logic; B1 : in std_logic; C1 : out std_logic; -- rad 3 A2 : in std_logic_vector(1 downto 0); B2 : in std_logic_vector(1 downto 0); C2 : out std_logic_vector(1 downto 0); -- rad 5 A3 : in std_logic_vector(2 downto 0); B3 : in std_logic_vector(2 downto 0); C3 : out std_logic_vector(2 downto 0)); end KZT; Sčítačka KZT(5,3,2) ve VHDL architecture A1 of KZT is begin C1 <= A1 xor B1; C2(0) <= (not A2(1) and not A2(0) and not B2(1) and B2(0)) or (not A2(1) and A2(0) and not B2(1) and not B2(0)) or (A2(1) and not A2(0) and B2(1) and not B2(0)); C2(1) <= (not A2(1) and not A2(0) and B2(1) and not B2(0)) or (not A2(1) and A2(0) and not B2(1) and B2(0)) or (A2(1) and not A2(0) and not B2(1) and not B2(0)); -- zde bude implementace radu 5 end A1;
ALU v kódu zbytkových tříd A bin2kzt B bin2kzt ALU KZT kzt2bin C Vyplatí se to? selektor funkce (+,-,*)
Literatura Drábek, V.: Výstavba počítačů, skriptum VUT v Brně, 1995.