Frekvenční analýza
Kapitoly: Kryptografie, Frekvenční analýza
Frekvenční analýza je obecný postup, který lze použít během luštění několika různých druhů šifer. Ve frekvenční analýze typicky procházíme šifrový text a snažíme se najít nějaké podobnosti s jazykem, ve kterém je zpráva psaná.
Četnost písmen v českém textu
Jedním ze základních prostředků frekvenční analýzy je četnost znaků v daném jazyku. Pokud analyzujeme dostatečné množství českého textu, můžeme spočítat různé statistické informace, včetně toho, kolikrát se v těchto textech vyskytovala jaká písmena.
Protože jsem onehdá na uložto zakoupil asi pět tisíc česky psaných knih, provedl jsem nad nimi takovou analýzu. V těch pěti tisíc knihách se celkem vyskytovalo 1 404 443 151 písmen. Rozložení písmen (po odstranění diakritiky) ukazuje následující tabulka:
Písmeno | Počet výskytů | Písmeno | Počet výskytů |
---|---|---|---|
a | 134 675 829 | n | 83 104 322 |
b | 24 944 593 | o | 112 776 769 |
c | 42 120 335 | p | 43 747 863 |
d | 53 015 496 | q | 83 322 |
e | 153 141 622 | r | 61 750 942 |
f | 2 458 624 | s | 78 451 777 |
g | 3 087 128 | t | 75 633 324 |
h | 35 075 708 | u | 50 265 458 |
i | 93 903 002 | v | 55 510 103 |
j | 32 383 080 | w | 762 129 |
k | 49 549 907 | x | 504 334 |
l | 80 345 129 | y | 40 132 126 |
m | 50 636 489 | z | 46 383 740 |
Následující tabulka pak ukazuje relativní četnost písmen:
Písmeno | Relativní četnost | Písmeno | Relativní četnost |
---|---|---|---|
a | 0.09589269 | n | 0.05917244 |
b | 0.0177612 | o | 0.08029999 |
c | 0.02999077 | p | 0.03114961 |
d | 0.03774841 | q | 0.00005933 |
e | 0.10904081 | r | 0.04396827 |
f | 0.0017506 | s | 0.0558597 |
g | 0.00219812 | t | 0.05385289 |
h | 0.02497482 | u | 0.03579031 |
i | 0.06686138 | v | 0.03952464 |
j | 0.02305759 | w | 0.00054266 |
k | 0.03528082 | x | 0.0003591 |
l | 0.05720782 | y | 0.02857512 |
m | 0.0360545 | z | 0.03302643 |
Tabulka tak říká, že přibližně 9,58 % písmen ve všech knihách bylo písmeno „a“. Odtud můžeme odvodit, že v běžném českém textu bude přibližně 9,58 % písmen právě „a“.
Každá taková statistika bude ukazovat trochu jiné hodnoty, ale to nevadí — nejde ani tak o přesné hodnoty, ty stejně nejde zjistit, stačí přibližné hodnoty.
Odchylka četnosti písmen od četnosti písmen v jazyku
Známe-li očekávané relativní četnosti jednotlivých písmen v daném jazyku, můžeme spočítat odchylku nějakého textu od očekávaných hodnot. Pro příklad si vezměmě dva texty: „fhes dudy fqhup ijhecuc fhejepu eriqxkzu ahkpdysu“ a „proc neni parez stromem protoze obsahuje kruznice“. Na první pohled vidíme, že první text je nějaká hatlamatlatilka, zatímco druhá věta je český text. Spočítáme si odchylku — měla by vyjít tak, že odchylka prvního textu bude zásadně vyšší než druhého.
Nejprve si spočítáme výskyty písmen v jednotlivých textech:
Písmeno | Počet písmen | Relativní četnost | |||
---|---|---|---|---|---|
První text | Druhý text | První text | Druhý text | Český jazyk | |
a | 1 | 2 | 0.02326 | 0.04651 | 0.09589 |
b | 0 | 1 | 0 | 0.02326 | 0.01776 |
c | 2 | 2 | 0.04651 | 0.04651 | 0.02999 |
d | 3 | 0 | 0.06977 | 0 | 0.03775 |
e | 5 | 6 | 0.11628 | 0.13953 | 0.10904 |
f | 3 | 0 | 0.06977 | 0 | 0.00175 |
g | 0 | 0 | 0 | 0 | 0.0022 |
h | 5 | 1 | 0.11628 | 0.02326 | 0.02497 |
i | 2 | 2 | 0.04651 | 0.04651 | 0.06686 |
j | 2 | 1 | 0.04651 | 0.02326 | 0.02306 |
k | 2 | 1 | 0.04651 | 0.02326 | 0.03528 |
l | 0 | 0 | 0 | 0 | 0.05721 |
m | 0 | 2 | 0 | 0.04651 | 0.03605 |
n | 0 | 3 | 0 | 0.06977 | 0.05917 |
o | 0 | 5 | 0 | 0.11628 | 0.0803 |
p | 3 | 3 | 0.06977 | 0.06977 | 0.03115 |
q | 2 | 0 | 0.04651 | 0 | 0.00006 |
r | 1 | 5 | 0.02326 | 0.11628 | 0.04397 |
s | 2 | 2 | 0.04651 | 0.04651 | 0.05586 |
t | 0 | 2 | 0 | 0.04651 | 0.05385 |
u | 6 | 2 | 0.13953 | 0.04651 | 0.03579 |
v | 0 | 0 | 0 | 0 | 0.03952 |
w | 0 | 0 | 0 | 0 | 0.00054 |
x | 1 | 0 | 0.02326 | 0 | 0.00036 |
y | 2 | 0 | 0.04651 | 0 | 0.02858 |
z | 1 | 3 | 0.02326 | 0.06977 | 0.03303 |
Nyní vypočítáme odchylky. Ty vypočítáme tak, že odečteme relativní četnost písmene v jazyku od relativní četnosti v prvním textu a umocníme na druhou. Tzn., že pro písmeno „a“ a první text bychom odchylku získali jako
$$ (0.0232558 - 0.0958927)^2=0.0052761 $$
a podobně pro všechny ostatní písmena. Pokud myší najedete na buňku s výsledkem, zobrazí se i výraz, tkerým se k výsledku došlo.
Relativní četnost | Odchylka | ||||
---|---|---|---|---|---|
1. text | 2. text | Český jazyk | 1. text | 2. text | |
a | 0.02326 | 0.04651 | 0.09589 | 0.0052761 | 0.0024385 |
b | 0 | 0.0232558 | 0.0177612 | 0.0003155 | 0.0000302 |
c | 0.0465116 | 0.0465116 | 0.0299908 | 0.0002729 | 0.0002729 |
d | 0.0697674 | 0 | 0.0377484 | 0.0010252 | 0.0014249 |
e | 0.1162791 | 0.1395349 | 0.1090408 | 0.0000524 | 0.0009299 |
f | 0.0697674 | 0 | 0.0017506 | 0.0046263 | 0.0000031 |
g | 0 | 0 | 0.0021981 | 0.0000048 | 0.0000048 |
h | 0.1162791 | 0.0232558 | 0.0249748 | 0.0083365 | 0.000003 |
i | 0.0465116 | 0.0465116 | 0.0668614 | 0.0004141 | 0.0004141 |
j | 0.0465116 | 0.0232558 | 0.0230576 | 0.0005501 | 0 |
k | 0.0465116 | 0.0232558 | 0.0352808 | 0.0001261 | 0.0001446 |
l | 0 | 0 | 0.0572078 | 0.0032727 | 0.0032727 |
m | 0 | 0.0465116 | 0.0360545 | 0.0012999 | 0.0001094 |
n | 0 | 0.0697674 | 0.0591724 | 0.0035014 | 0.0001123 |
o | 0 | 0.1162791 | 0.0803 | 0.0064481 | 0.0012945 |
p | 0.0697674 | 0.0697674 | 0.0311496 | 0.0014913 | 0.0014913 |
q | 0.0465116 | 0 | 0.0000593 | 0.0021578 | 0 |
r | 0.0232558 | 0.1162791 | 0.0439683 | 0.000429 | 0.0052289 |
s | 0.0465116 | 0.0465116 | 0.0558597 | 0.0000874 | 0.0000874 |
t | 0 | 0.0465116 | 0.0538529 | 0.0029001 | 0.0000539 |
u | 0.1395349 | 0.0465116 | 0.0357903 | 0.0107629 | 0.0001149 |
v | 0 | 0 | 0.0395246 | 0.0015622 | 0.0015622 |
w | 0 | 0 | 0.0005427 | 3e-7 | 3e-7 |
x | 0.0232558 | 0 | 0.0003591 | 0.0005243 | 1e-7 |
y | 0.0465116 | 0 | 0.0285751 | 0.0003217 | 0.0008165 |
z | 0.0232558 | 0.0697674 | 0.0330264 | 0.0000955 | 0.0013499 |
0.0558546 | 0.0211603 |
Nakonec jsme všechny odchylky sečetly. Správně bychom ještě měli tuto hodnotu vydělit počtem písmen a následně odmocnit, abychom opravdu dostali odchylku. Ale tyto operace už nic nezmění na tom, že druhý text má odchylku výrazně nižší, takže je s mnohem větší pravděpodobností text českého jazyka.
Nejčastější slova jazyka
Občas se může hodit i seznam nejčastějších slov jazyka.
Slovo | Výskytů | Slovo | Výskytů | Slovo | Výskytů | Slovo | Výskytů |
---|---|---|---|---|---|---|---|
jsem | 2 516 782 | tady | 286 606 | rekla | 203 656 | snad | 163 296 |
jako | 1 321 843 | dobre | 273 130 | zeptal | 201 509 | ruce | 161 382 |
kdyz | 1 237 411 | chvili | 269 045 | mela | 199 285 | taky | 161 174 |
jeho | 974 131 | vsechno | 268 277 | pokud | 197 778 | videl | 160 506 |
bylo | 689 849 | jestli | 262 429 | takze | 193 357 | prece | 160 228 |
byla | 657 760 | proc | 262 226 | pane | 193 123 | prilis | 156 839 |
rekl | 644 137 | nikdy | 260 096 | vsechny | 192 988 | misto | 156 221 |
jeste | 608 371 | mohl | 259 919 | vsichni | 185 965 | kterou | 155 250 |
jsme | 549 840 | byly | 255 072 | potom | 183 655 | zase | 154 924 |
ktery | 522 587 | mezi | 253 466 | vubec | 179 968 | dost | 154 784 |
nebo | 489 592 | kolem | 251 146 | svou | 178 390 | nekolik | 154 165 |
ktere | 483 800 | tomu | 243 646 | rychle | 175 422 | hlavou | 153 777 |
pred | 460 548 | znovu | 235 604 | trochu | 174 553 | abych | 153 655 |
neco | 448 947 | mozna | 235 161 | stale | 174 451 | podle | 151 450 |
toho | 446 667 | prave | 233 467 | sebou | 173 820 | zacal | 151 309 |
bude | 412 128 | muze | 227 622 | jenom | 172 716 | clovek | 149 240 |
jste | 394 867 | take | 224 705 | kteri | 172 342 | chtel | 148 978 |
jsou | 376 431 | dalsi | 221 056 | lidi | 169 569 | proti | 148 603 |
jejich | 331 235 | stejne | 218 216 | tohle | 167 825 | nebyl | 147 829 |
neni | 318 782 | kdyby | 217 917 | nekdo | 165 736 | velmi | 145 921 |
bych | 304 981 | sebe | 211 148 | prvni | 164 858 | dvere | 141 094 |
protoze | 302 978 | nich | 210 384 | proto | 164 817 | veci | 140 673 |
vsak | 301 623 | jeden | 208 864 | tedy | 164 637 | vedel | 140 656 |
ktera | 295 817 | byli | 206 830 | nikdo | 164 442 | myslim | 139 935 |
jeji | 288 095 | pres | 205 040 | sveho | 163 638 | nebylo | 136 314 |