Malá hra o velkého Bajta (4) - Vigenérova šifra

Místo pro dotazy a rady ohledně programovacích jazyků (C++, C#, PHP, ASP, Javascript, VBS..) a tvorby webových stránek

Moderátor: Mods_senior

Uživatelský avatar
faraon
Master Level 8
Master Level 8
Příspěvky: 5968
Registrován: prosinec 10
Pohlaví: Muž

Malá hra o velkého Bajta (4) - Vigenérova šifra

Příspěvekod faraon » 17 led 2016 00:55

Všechny bity hry:

00000001 - Jednoduchá kalkulačka
00000010 - Odebírání zápalek
00000100 - Gregoriánský kalendář
00001000 - Hádání kombinace
00010000 - Vigenérova šifra
00100000 - Hledání min
01000000 - Házení kostkou
10000000 - Conway's Game of Life




Minulý bit Malé hry o Velkého Bajta moc účastníků nepřitáhl, doufám že ne pro svoji nevelkou obtížnost, ale spíš proto že se kolem nás děje hromada zajímavějších věcí, než je společenská stolní hra vyžadující logické uvažování. Spousta těch zajímavostí naopak jakoukoliv logiku popírá, ba často i vylučuje. Politici ve jménu boje proti terorizmu volají po zpřísnění podmínek a nejlépe zákazu šifrování, a vesele ignorují skutečnost že pařížští vrazi žádné šifrování nepoužívali, nehledě na to že ve Francii je už dávno zakázané. Stejně tak volají po zvýšení rozpočtů tajných služeb, kterým ale v posledních letech rozpočty prudce rostly, jenom se to jaksi neprojevilo na jejich výkonech, natož schopnostech. A volají i po dalších zákazech a nařízeních, jaké nebyly běžné ani v nejhorších totalitních režimech minulosti, jako by jejich největší touhou bylo terorizovat vlastní voliče...
Takže, co provést, aby naše dopisy či maily nečetl každý úchyl a fízl, kterému se dostanou do jeho předlouhých a nikým nekontrolovaných pařátů? Musíme pro to udělat trochu víc než jenom říct:

Nešmíruj, šmíráku!

Například je potřeba umět svojí korespondenci zašifrovat a také rozšifrovat. Dnes s počítači, tablety a mobily chytřejšími než jejich uživatelé je to celkem jednoduché, ale může se stát že žádný takový přístroj zrovna nebude po ruce, nebo ho nebude možné z jakéhokoliv důvodu použít, a tak je potřeba umět nějakou šifru používat jenom s tužkou a papírem. Pro to se moderní počítačové šifry vůbec nehodí, je potřeba sáhnout trochu hlouběji do historie.

Nejrůznější tajná písma, číselné kódy a chlívkové šifry používané ke hrám na dětských táborech je možné rovnou zavrhnout, protože k ničemu jinému než dětskému hraní se nehodí. Stejně špatně je na tom i slavná Caesarova šifra, vyskytující se dnes v "důvěrné" komunikaci na některých internetových fórech v obměně zvané ROT13:

Kód: Vybrat vše

ABCDEFGHIJKLM
NOPQRSTUVWXYZ


Je to prostě abeceda přestřižená napůl, a složená pod sebe, odpovídá tak Caesarově šifře s posunem 13. Při šifrování nebo dešifrování se písmeno z jenoho řádku nahradí písmenem z druhého. ROT13 se vzdáleně podobá starověké šifře Atbaš, vyskytující se v hebrejských svitcích, ta se liší tím že ta přestřižená abeceda není posunutá pod sebe, ale zlomená napůl:

Kód: Vybrat vše

ABCDEFGHIJKLM
ZYXWVUTSRQPON


Říká se tomu odborně reciproká abeceda, použití šifry je stejné jako v minulém případě. Obrácení pořadí písmen má jednu velkou výhodu, zatímco při běžném pořadí jsou pro šifrování a dešifrování potřeba dva různé procesy, u reciprokých šifer stačí jenom jeden, protože dochází k zrcadlovému efektu. Tím se zjednoduší používání a sníží se také riziko chyb šifranta.
Bezpečnost takhle jednoduchých šifer je velmi nízká, Caesarova šifra podlehla arabským luštitelům už v devátém století, ti evropští měli za nimi jenom 400 let zpoždění. Kteroukoliv substituční monoalfabetickou šifru (takovou kde se jedna abeceda nahrazuje druhou) je možné pomocí počítače zlomit za pár tisícin sekundy.

Další možností utajení zprávy je zpřeházení písmen textu podle domluveného klíče. Existuje spousta transpozičních šifer, od psaní pozpátku přes kryptex, otočné a překlápěcí šifrovací mřížky, všelijaké míchání sloupců a řádků, až k moderním matematickým variacím jako je americký DES, ale ty, které jsou použitelné kdekoliv v terénu, by počítači neodolaly déle než pár minut. Daní za jejich rostoucí složitost by mohlo být i několikahodinové ruční luštění, což je velmi otravná práce s velkou pravděpodobností chyb. Takže tudy cesta také nevede.

Už někdy ve čtrnáctém století se objevila myšlenka, která způsobila šifrovací revoluci - použití více šifrových abeced. Nejdřív dvě, pak čtyři, potom třináct, což už je půlka abecedy, a ve století šestnáctém konečně došlo k použití stejného počtu šifrových abeced, jako má abeceda písmen! Popsal jí ve své knize francouzský diplomat Blaise de Vigenére, který sice nebyl jejím vynálezcem, ale jak už to bývá, je s ní spojován dodnes a šifra nese jeho jméno. Po několik staletí byla považována za nerozluštitelnou, a také se tak nazývala: Vigenérova šifra - Le Chiffre Indéchiffrable.

Vrcholem polyalfabetických šifer byla šifra Vernamova, která vznikla na konci První světové války, a která je jedinou šifrou s matematicky prokázanou nerozluštitelností. Ta byla také první, kterou používaly telekomunikační stroje - dálnopisy. V Německu o málo později vznikl slavný šifrovací stroj Enigma, který používá několikanásobné polyalfabetické šifrování, ale jeho systém byl poměrně brzy prolomen polskými matematiky, což přispělo k rychlejší porážce nacistického režimu.
Pro strojní šifry je potřeba šifrovací přístroj, ale ten je problém přenášet a ukrýt před zvědavci (Enigma byl kufr těžký dvanáct kilogramů), což je vylučuje z našeho okruhu. Pomůcky pro šifrování je také potřeba nenápadně ukrýt, nebo jimi musí být úplně běžné předměty, které u sebe může mít každý, aniž by vzbudily podezření.

A proto právě Vigenérova šifra je úkolem pro bit 00010000.

Pro její používání stačí pouze tužka a papír, šifrovací tabulku je možné mít složenou třeba v peněžence nebo se dá během chvilky vytvořit kdykoliv je potřeba, a také je jí možno nahradit šifrovacím diskem, který americká armáda používala od dob Občanské války až po Druhou světovou. Tohle je můj osobní, s vnitřním kotoučem otočeným na stranu s reciprokou abecedou:


sifdisk.png


V té době sice už dávno existovala metoda pro její rozluštění, ale byla to velmi zdlouhavá a náročná činnost. Jako první jí objevil anglický matematik Charles Babbage, vynálezce prvního programovatelného počítače. Princip šifrování je jednoduchý, odesílatel i příjemce mají smluvené heslo, kterým se text zprávy zašifruje. Heslo bývá slovo nebo věta, která se dobře pamatuje, a pro celou zprávu se neustále opakuje. To opakování je slabé místo Vigenérovy šifry. Pro ukázku použijeme heslo OKURKA:

Kód: Vybrat vše

heslo: OKUR KAO K URKAOKU RKAOK
text:  MALÁ HRA O VELKÉHO BAJTA


Mezery se přeskakují a v šifrovaném textu úplně vynechávají, aby případnému luštiteli neusnadňovaly práci. Pro šifrování je potřeba výše zmíněná tabulka:

recvigtab.png


Postup šifrování/dešifrování je jednoduchý:

  1. Podle písmene hesla vybereme v tabulce správný řádek.
  2. Najdeme na něm písmeno textu, a z horního obráceného řádku ve stejném sloupci opíšeme písmeno šifry.

Písmeno hesla určuje o kolik bude šifrová abeceda posunutá vůči skutečné:

První písmeno hesla je O, první písmeno zprávy je M, tomu odpovídá zašifrované písmeno B.
Druhé písmeno hesla je K, druhé písmeno zprávy je A, tomu odpovídá zašifrované písmeno J.
Třetí písmeno hesla je U, třetí písmeno zprávy je L, tomu odpovídá zašifrované písmeno I:

Kód: Vybrat vše

OKUR KAO K URKAOKU RKAOK
MALÁ HRA O VELKÉHO BAJTA
BJI...


A tak to děláme pořád dokola, písmenko po písmenku, až zašifrujeme celou zprávu. Také je možné písmeno textu najít v horním obráceném řádku a písmeno šifry ve vybraném, díky reciprokému pořadí je to v obou případech stejná dvojice (na rozdíl od původní Vigenérovy šifry s abecedami v přirozeném pořadí). Pro urychlení práce lze celou zprávu rozepsat pod jednou napsané heslo, a šifrovat jí po sloupcích, vždy podle stejného písmena hesla. Není ho tak potřeba hledat znovu při každém opakování:

Kód: Vybrat vše

OKURKA   O...
------   ------
MALÁHR   B
AOVELK   N
ÉHOBAJ   J
TA       U


Již zašifrovaný sloupec otevřeného textu je dobré pro přehlednost proškrtnout, aby se nám už nepletl. Po zašifrování se celá zpráva opět opíše po řádcích a vyjde stejný kód jako při předchozím postupu. Dešifrování proběhne zase úplně stejně, vlastně se při něm šifrovaný text ještě jednou zašifruje stejným heslem, a tím se opět odkryje. Díky tomu se program pro počítač velmi zjednoduší, protože nemusí umět dvě různé činnosti, ale vystačí jenom s jednou.

Vigenérova šifra není neprolomitelná, ale je možné jí použít na kratší zprávy, při dodržení několika pravidel:

  1. Heslo musí být dostatečně dlouhé aby se opakovalo co nejméně, v ideálním případě stejně dlouhé jako je zpráva, mělo by být složené z náhodných znaků a neobsahovat existující slova.
  2. Žádné heslo se nikdy nesmí použít dvakrát, protože porovnáním dvou zpráv zašifrovaných stejným heslem je možné i bez znalosti jejich obsahu to heslo odhalit, a obě zprávy potom rozšifrovat.
  3. Ani zpráva se nesmí zašifrovat dvakrát různým heslem, protože stejně jako v předchozím případě je možné porovnáním odhalit původní zprávu i bez znalosti těch hesel.




Takže úkol tohoto kola je napsat program, který bude šifrovat heslem, podle reciproké tabulky, Vigenérovou šifrou. Musí dodržet několik zásad, aby různé programy stejné zprávy zašifrovaly stejně:

  1. Mezery a veškeré bílé znaky se vynechávají, jako by neexistovaly.
  2. Jiné znaky v textu, které nejsou v šifrovací tabulce (třeba číslice, otazník, vykřičník...), se nešifrují, ale ponechají tak jak jsou.
  3. Písmena s diakritikou se buď převedou na písmena bez diakritiky, nebo se berou jako znaky které nejsou v tabulce, viz předchozí bod (jak kdo uzná za vhodné).
  4. Heslo může obsahovat pouze znaky které jsou v tabulce (takže ABCDEFGHIJKLMNOPQRSTUVWXYZ nebo abcdefghijklmnopqrstuvwxyz), ostatní se vyhází.
  5. Text se po zašifrování/dešifrování vypisuje ve "slovech" po pěti písmenech, aby se dal snadno a bez chyb opsat z papíru nebo na papír. A bylo by dobré tuhle nudli občas zalomit na další řádek, třeba na šířku stránky (80 sloupců).

Jsem zvědavý, kdo dokáže jako první rozluštit tenhle text:

Kód: Vybrat vše

WIWTP QNJHD S,UCA BQQKE WZYVN I,YGE HSDLJ NLHYW CNGMS XEJ,O TBUDZ LVRSX YRSBO XVBBI QA,FT XEOHV
WICPG RFUZF ICQGU SHYSI YVBZW CAECP QWDSM JZJEE JV.WG XZAUL GOZHK WQQKW HQLMG EWAQL KVART IGVSN
YZSVL YGTFQ CBIIV HFTFR JSMYI ,QNKP LBRIZ XKUYH SRYVL IMFKJ YRIGK NBWKO XTCXW SNFGC PVAI. NVOXV
IMKHL MADJD YJQYN BYIXM LHXZR MGZZF ICMGO G,VOY XGREM HQJCK KYXSW SGWYH DZVOY GZLQV TFLCA S,JSX
NPZVT MZOHD PFTIS WPOX. UVRFP D.


Heslo je "Mala hra o velkeho Bajta".
Nemáte oprávnění prohlížet přiložené soubory.
Naposledy upravil(a) faraon dne 03 dub 2016 23:12, celkem upraveno 3 x.


Nejhroznější sen linuxáka: nabootuje počítač, a tam Windows.
Nejhroznější sen windowsáka: nabootuje počítač, a tam Linux.
Nejkrásnější sen linuxáka: nabootuje počítač, a tam Linux.
Nejkrásnější sen windowsáka: nabootuje počítač.

Reklama
Uživatelský avatar
ITCrowd
Tvůrce článků
Elite Level 11
Elite Level 11
Příspěvky: 13250
Registrován: březen 10
Pohlaví: Muž

Re: Malá hra o Velkého Bajta (4)

Příspěvekod ITCrowd » 17 led 2016 20:12

Pěkné!
Jen bych doplnil - z hlediska kryptografie není žádná šifra neprolomitelná. Základní podmínkou je, že rozumíme jazyku, ve kterém je původní zpráva napsána. To byl taky důvod, proč se japoncům nepovedlo prolomit kód navaho. Druhým faktorem je čas. Pokud bych rozluštil zprávu až za dvacet let, tak už nebude mít žádnou hodnotu.
Kolem Enigmy - polákům hodně pomohli francouzi, kterým se přihlásil "špion" Hans-Thilo Schmidt, který za peníze tajemství enigmy francii prodal. Francouzi poté předali tohle polákům, kterým se podařilo enigmu rozluštit mimo jiné i díky tomu, že otevřeli zásilku pro německé velvyslanectví. Mám dojem, že i stroj "bomba" vystavený v Bletchley parku, který byl po dobu války mnohokrát upravován, zkonstruovali poláci.
Zkusili jste to vypnout a zapnout? Problémy řeším pouze v tématech. Do SZ mi proto píšete zbytečně.
Základní diagnostika WiFi Jak na diagnostiku sítě Router jako switch Proč je nesmysl chtít router s velkým dosahem

Uživatelský avatar
faraon
Master Level 8
Master Level 8
Příspěvky: 5968
Registrován: prosinec 10
Pohlaví: Muž

Re: Malá hra o Velkého Bajta (4)

Příspěvekod faraon » 17 led 2016 21:45

Žádná šifra není nerozluštitelná, kromě té Vernamovy. A to ještě jenom za podmínky dodržení těch tří pravidel která jsem napsal, stačí udělat jedinou chybu a padne i ta. Na bod 3 se za války podařilo prolomit německou šifru Lorenz, která byla mnohem komplikovanější a bezpečnější než Enigma!

Ono to lámání Enigmy byla dost dobrodružná historie, podstatné je že vojenský model se od civilního lišil zapojením, které se tenkrát Marianovi Rejewskému podařilo víceméně uhádnout, částečně i díky příručce kterou dostali od Francouzů, ti si mysleli že je to nemožné a tak se podělili se spojenci o "bezcennou" informaci. Zbytek jeho úspěchu byla velmi tvrdá práce trvající několik let. Ale odměnou mu bylo to, že když se Hitler v roce 1934 dostal k moci, tak polská tajná služba už několik let znala obsah všech německých depeší, které se jí podařilo zachytit...
Tři dny před napadením Polska pracovníci Biura szyfrów všechno co měli odvezli letadlem do Británie, tamní kryptologové z toho padali do mdlob, ale velmi rychle se jim podařilo polskou Bombu vylepšit a vyrobit v mnohem větším počtu, na což už Poláci neměli čas ani peníze. Na oplátku je od luštění německých kódů úplně odstavili, takže Rejevski se o svém důležitém podílu na vítězství Spojenců dozvěděl až v roce 1975!
Později pod vedením Alana Turinga dokonce vznikl speciální elektronický počítač Colossus, který zjišťoval denní nastavení mnohem rychleji než mechanické Bomby. Něco málo z historie Bletchley Parku se dá vidět ve filmu Enigma. Zato ten slavný velkofilm U-571 je totální slátanina úplně vycucaná z prstu, podobně jako většina lživé hollywoodské propagandy.

Tak doufám že se tentokrát zúčastníš, ten zašifrovaný textík je takový vtipný bonbónek pro počítačové nadšence, a kromě toho slouží i jako kontrola kompatibility různých implementací - aby různými způsoby vyšel vždy stejný výsledek.

Na kódu Navaho je nejvtipnější to, že to vůbec není šifra. Velmi podobná věc se v menším měřítku používala už za První světové, a několikrát dokonce předtím. Indiáni jsou dobrá zbraň :)
Nejhroznější sen linuxáka: nabootuje počítač, a tam Windows.
Nejhroznější sen windowsáka: nabootuje počítač, a tam Linux.
Nejkrásnější sen linuxáka: nabootuje počítač, a tam Linux.
Nejkrásnější sen windowsáka: nabootuje počítač.

Uživatelský avatar
ITCrowd
Tvůrce článků
Elite Level 11
Elite Level 11
Příspěvky: 13250
Registrován: březen 10
Pohlaví: Muž

Re: Malá hra o Velkého Bajta (4)

Příspěvekod ITCrowd » 17 led 2016 22:30

No, co se týče této šifry, tak je tam zajímavý paradox:
jestliže pro nerozluštění potřebuji klíč stejně dlouhý jako šifrovaný text, pak potřebuji bezpečný kanál, jak tento klíč doručit příjemci zprávy. A pokud tento bezpečný kanál mám, pak můžu text tímto bezpečným kanálem přenést nezašifrovaný :-)
Zkusili jste to vypnout a zapnout? Problémy řeším pouze v tématech. Do SZ mi proto píšete zbytečně.
Základní diagnostika WiFi Jak na diagnostiku sítě Router jako switch Proč je nesmysl chtít router s velkým dosahem

Uživatelský avatar
faraon
Master Level 8
Master Level 8
Příspěvky: 5968
Registrován: prosinec 10
Pohlaví: Muž

Re: Malá hra o Velkého Bajta (4)

Příspěvekod faraon » 17 led 2016 23:11

A je to tu zase. Klíč je chybný překlad z angličtiny, v českém názvosloví se jím označuje typ šifry. To čím se text zašifruje je heslo!

Ale jinak máš pravdu, na samotné šifře nezáleží, sebesložitější systém dřív nebo později podlehne. A čím je složitější, tím víc může obsahovat chyb které usnadní jeho dřívější prolomení... Zatímco na Vernamovu šifru stačí jenom pět obyčejných relátek, je tak primitivní že už nejde víc zjednodušit. Rozhodující faktor je právě bezpečnost hesla, a distribuce hesel je největší problém kryptografie.

Rozdíl je v tom, že ta hesla je možné převézt najednou, v krátkém okamžiku kdy se podaří bezpečný kanál vytvořit, ale jimi zašifrované zprávy potom lze posílat v libovolnou dobu jakýmkoliv nezabezpečeným způsobem. Proto špioni svoje jednorázové tabulky velmi dobře ukrývají a střeží ;-)
Nejhroznější sen linuxáka: nabootuje počítač, a tam Windows.
Nejhroznější sen windowsáka: nabootuje počítač, a tam Linux.
Nejkrásnější sen linuxáka: nabootuje počítač, a tam Linux.
Nejkrásnější sen windowsáka: nabootuje počítač.

Denis V.
Level 3.5
Level 3.5
Příspěvky: 980
Registrován: květen 13
Pohlaví: Muž

Re: Malá hra o Velkého Bajta (4)

Příspěvekod Denis V. » 21 led 2016 18:35

Nějak jsem si nevšiml že vyšly nové díly, o víkendu se pokusím dodělat tento i minulý díl :) omlouvám se za ot

Uživatelský avatar
Tomasb98
Level 4
Level 4
Příspěvky: 1011
Registrován: červen 13
Bydliště: Hradec Králové
Pohlaví: Muž

Re: Malá hra o Velkého Bajta (4)

Příspěvekod Tomasb98 » 06 úno 2016 21:45

Tak jsem si s tím několik minut hrál, ale ten text se mi nepovedlo dešifrovat... a zdrojáky (C#) hodím zítra.
Nemáte oprávnění prohlížet přiložené soubory.

Uživatelský avatar
faraon
Master Level 8
Master Level 8
Příspěvky: 5968
Registrován: prosinec 10
Pohlaví: Muž

Re: Malá hra o Velkého Bajta (4)

Příspěvekod faraon » 06 úno 2016 22:03

Otestoval jsem to v mém programu a tvůj text se mi zašifroval i rozšifroval úplně stejně. Ale nevypsal se ti na konci ten otazník, který by jako neznámý znak měl zůstat nezměněný, nebude problém v tomhle?

Kód: Vybrat vše

HRAHRAHRAH
AHOJ,LIDI!
GJLX,OYNR!
Nejhroznější sen linuxáka: nabootuje počítač, a tam Windows.
Nejhroznější sen windowsáka: nabootuje počítač, a tam Linux.
Nejkrásnější sen linuxáka: nabootuje počítač, a tam Linux.
Nejkrásnější sen windowsáka: nabootuje počítač.

Uživatelský avatar
Tomasb98
Level 4
Level 4
Příspěvky: 1011
Registrován: červen 13
Bydliště: Hradec Králové
Pohlaví: Muž

Re: Malá hra o Velkého Bajta (4)

Příspěvekod Tomasb98 » 06 úno 2016 22:24

Jo v tom to bude, já prostě odstranil všechny znaky kromě písmen (písmena s diakritikou jsem převedl na písmena bez...), proto ten začátek vypadal slibně a až za tou čárkou to byl nesmysl.

Uživatelský avatar
Tomasb98
Level 4
Level 4
Příspěvky: 1011
Registrován: červen 13
Bydliště: Hradec Králové
Pohlaví: Muž

Re: Malá hra o Velkého Bajta (4)

Příspěvekod Tomasb98 » 07 úno 2016 14:26

Tak nakonec se podařilo a text pobavil :-)

Zdrojáky programu
Nemáte oprávnění prohlížet přiložené soubory.

someoneFromSomewhere
nováček
Příspěvky: 20
Registrován: květen 17
Pohlaví: Muž

Re: Malá hra o velkého Bajta (4) - Vigenérova šifra

Příspěvekod someoneFromSomewhere » 19 kvě 2017 22:27

Už jsem tady zas!


Moje vcelku jednoduché řešení. Tentokrát s podstatnou paměťovou náročností a mým úchylným formátováním výstupu do konzole. :twisted: :lol: :lol:

Kód: Vybrat vše

#include <iostream>
#include <string>

std::string normalize(const std::string& raw) {
   std::string ret("");
   for (const char& c : raw) {
      if (isspace(c)) continue;
      ret += (isalpha(c) ? (isupper(c) ? c : toupper(c)) : c);
   }
   return ret;
}

std::string encode(const std::string& raw_text, const std::string& raw_password) {
   std::string text(normalize(raw_text)), password(normalize(raw_password)), encoded("");
   std::size_t p_iter = 0;
   for (const char& c : text) {
      encoded += (isalpha(c) ? (password[p_iter] + 25 - c) % 26 + 'A' : c);
      if (++p_iter >= password.size()) p_iter = 0;
   }
   return encoded;
}

int main(int argc, char** argv) {
   std::string text, pass, outp;
   std::cout << "-------------------- Vlozte sifrovaci heslo: \n";
   std::getline(std::cin, pass);
   std::cout << "-------------------- Vlozte prisne tajny text pro zasifrovani / odsifrovani: \n";
   std::getline(std::cin, text);
   outp = encode(text, pass);
   std::cout << "-------------------- Vysledek: \n";
   for (std::size_t i = 0; i < outp.size(); i++) {
      if (i % 5 == 0) std::cout.put(' ');
      if (i % 40 == 0) std::cout.put('\n');
      std::cout.put(outp[i]);
   }

   std::cin.get();
   return 0;
}


A co se toho zašifrovaného týče, tak i s tebou, bratře, return.
std::endl není nový řádek!

Uživatelský avatar
faraon
Master Level 8
Master Level 8
Příspěvky: 5968
Registrován: prosinec 10
Pohlaví: Muž

Re: Malá hra o velkého Bajta (4) - Vigenérova šifra

Příspěvekod faraon » 20 kvě 2017 08:58

Tak tohle už mi kompilátor skousnul, i když jen se std=c++11. Předtím nějak nepobíral ty "range-based 'for' loops" :P

Formátování je úplně v pohodě, ale při prvním pokusu mi to rozšifrovalo jenom první řádek textu, který jsem zkopíroval přímo tady ze stránky, a další už program ignoroval, protože skončil. Musel jsem nejdřív všechny řádky spojit - odstranit \n, a teprve pak to vzalo celý text.

A takhle jsem si hrál já, i s rozžvýkáním nabodeníček a kapitalizací:

Kód: Vybrat vše

#include <stdio.h>



/* převodní tabulka Unicode => ASCII */
int latinka[26][77]={{'A',97,192,193,194,195,196,197,224,225,226,227,228,229,256,257,258,259,260,261,461,462,478,479,480,481,506,507,512,513,514,515,550,551,7680,7681,7834,7840,7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855,7856,7857,7858,7859,7860,7861,7862,7863,11365,0},
                     {'B',98,7682,7683,7684,7685,7686,7687,0},
                     {'C',99,199,231,262,263,264,265,266,267,268,269,391,392,7688,7689,0},
                     {'D',100,270,271,272,273,393,394,7690,7691,7692,7693,7694,7695,7696,7697,7698,7699,0},
                     {'E',101,200,201,202,203,232,233,234,235,274,275,276,277,278,279,280,281,282,283,516,517,518,519,552,553,7700,7701,7702,7703,7704,7705,7706,7707,7708,7709,7864,7865,7866,7867,7868,7869,7870,7871,7872,7873,7874,7875,7876,7877,7878,7879,0},
                     {'F',102,401,402,7710,7711,7835,7836,7837,0},
                     {'G',103,284,285,286,287,288,289,290,291,403,608,484,485,486,487,500,501,7712,7713,0},
                     {'H',104,292,293,294,295,542,543,7714,7715,7716,7717,7718,7719,7720,7721,7722,7723,7830,11367,11368,0},
                     {'I',105,204,205,206,207,236,237,238,239,296,297,298,299,300,301,302,303,304,305,306,307,406,407,463,464,520,521,522,523,7724,7725,7726,7727,7880,7881,7882,7883,0},
                     {'J',106,308,309,496,0},
                     {'K',107,310,311,312,408,409,488,489,7728,7729,7730,7731,7732,7733,11369,11370,0},
                     {'L',108,313,314,315,316,317,318,319,320,321,322,321,410,7734,7735,7736,7737,7738,7739,7740,7741,11360,11361,11362,0},
                     {'M',109,7742,7743,7744,7745,7746,7747,0},
                     {'N',110,209,241,323,324,325,326,327,328,329,330,331,413,414,504,505,7748,7749,7750,7751,7752,7753,7754,7755,0},
                     {'O',111,210,211,212,213,214,216,242,243,244,245,246,248,332,333,334,335,336,337,338,339,416,417,465,466,490,491,492,493,510,511,524,525,526,527,554,555,556,557,558,559,560,561,7756,7757,7758,7759,7760,7761,7762,7763,7884,7885,7886,7887,7888,7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903,7904,7905,7906,7907,0},
                     {'P',112,7764,7765,7766,7767,11363,0},
                     {'Q',113,0},
                     {'R',114,340,341,342,343,344,345,528,529,530,531,7768,7769,7770,7771,7772,7773,7774,7775,11364,0},
                     {'S',115,346,347,348,349,350,351,352,353,536,537,7776,7777,7778,7779,7780,7781,7782,7783,7784,7785,0},
                     {'T',116,354,355,356,357,358,359,427,428,429,430,538,539,7786,7787,7788,7789,7790,7791,7792,7793,7831,11366,0},
                     {'U',117,217,218,219,220,249,250,251,252,360,361,362,363,364,365,366,367,368,369,370,371,431,432,467,468,469,470,471,472,473,474,475,476,532,533,534,535,7794,7795,7796,7797,7798,7799,7800,7801,7802,7803,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919,7908,7909,7920,7921,0},
                     {'V',118,7804,7805,7806,7807,11377,11380,0},
                     {'W',119,372,373,7808,7809,7810,7811,7812,7813,7814,7815,7816,7817,11378,11379,7832,0},
                     {'X',120,7818,7819,7820,7821,0},
                     {'Y',121,221,376,253,255,374,375,376,255,435,436,562,563,7822,7823,7833,7922,7923,7924,7925,7926,7927,7928,7929,0},
                     {'Z',122,437,438,377,378,379,380,381,382,548,549,7824,7825,7826,7827,7828,7829,11371,11372,0}};



/* čtení a převod na Unicode */
int input(void)
    {
    int kod=0,maska=128,znak,i,n;

    /* načtení písmene */
    do {
       znak=getchar();
       if (znak>=maska)                                         /* UTF-8 */
          {                                                     /* načte a spočítá sekvenci bajtů */
          for (n=0;znak&maska;++n,maska>>=1);                   /* spočítá masku */
          for (;maska;maska>>=1) if (znak&maska) kod+=maska;    /* vezme bity z hlavičky */
          for (i=1;i<n;++i) kod=(kod<<6)+(getchar()&63);        /* přidá bity z dat */
          }
       else                                                     /* ASCII */
          if (znak<'\0')                                        /* EOF nebo ^D */
             return znak;                                       /* vrátí rovnou */
          else
             if (znak>' ')                                      /* nebílé ASCII */
                {
                kod=znak;                                       /* nechá jak jsou */
                break;                                          /* a jde na převod */
                }
       } while (znak<=' ');                                     /* bílé znaky vyhazuje */

    /* odstranění diakritiky a převod na velké */
    for (i=0;i<26;++i)                                          /* všechny řádky */
        for (n=0;latinka[i][n];++n)                             /* jenom do \0 */
            if (kod==latinka[i][n])                             /* při shodě */
               return latinka[i][0];                            /* vrátí velké písmeno */

    return kod;                                                 /* jinak vrátí nepřevedené */
    }



/* převod z Unicode a výpis */
void output(int kod)
     {
     int i=5;
     unsigned char text[7]={0};

     if (kod<128)                                               /* ASCII */
        putchar(kod);                                           /* vypíše rovnou */
     else                                                       /* UTF-8 */
        {                                                       /* převede */
        for (;kod;--i)                                          /* dokud jsou data */
            {                                                   /* uložení sekvence do pole */
            text[0]=(text[0]>>1)+128;                           /* plnění masky */
            text[i]+=(kod&63)+128;                              /* data do pozice */
            kod>>=6;                                            /* uřízne použité bity */
            }                                                   /* a posune na předchozí pozici */
        text[++i]|=text[0];                                     /* přiložení masky */
        printf("%s",text+i);                                    /* vypíše řetězec od vypočtené pozice */
        }
     }



/*******************************************************************************/
int main(void)
    {
    int pismeno,delka,i,n;
    char heslo[100]={0};

    fprintf(stderr,"\nRecVig (C)2016 FARAON\n\n"
                   "Program pracuje s kódováním UTF-8,\n"
                   "nekontroluje chyby vstupu,\n"
                   "z latinky odstraní diakritiku.\n"
                   "Text se vypisuje do stdout,\n"
                   "hlášení do stderr.\n\n"
                   "Zadej heslo (max. 100 písmen A až Z):\n");

    /* načtení hesla */
    for (delka=0;delka<100;++delka)                             /* max 100 znaků */
        {
        while ((pismeno=getchar()&~' ')<'A' || pismeno>'Z')     /* malá na velká */
              if ('\n'==pismeno && delka) goto flush;           /* musí načíst aspoň jedno */
        heslo[delka]=pismeno;                                   /* vloží do hesla */
        }
    flush:
    while (pismeno!='\n') pismeno=getchar();                    /* zahodí přebytečný vstup */

    /* zašifrování vstupu */
    fprintf(stderr,"\nPiš text (konec=^D):\n");
    for (i=n=0;(pismeno=input())>0;i=(1+i)%delka)               /* dokud je písmeno */
        {
        if ('A'<=pismeno && pismeno <='Z')                      /* když je A..Z */
           pismeno=(heslo[i]+25-pismeno)%26+'A';                /* zašifruje ho */
        output(pismeno);                                        /* vypíše */
        if (!(++n%5)) putchar(n%80?' ':'\n');                   /* oddělující mezery a odřádkování */
        }                                                       /* vypočítá další pozici v heslu */
    output('\n');                                               /* po skončení odřádkuje */

    fprintf(stderr,"\nCelkem znaků:    %d\n"
                   "Opakování hesla: %d\n\n",n,n/delka);        /* trocha statistiky */
    return 0;
    }



/*******************************************************************************/

/* výpis vybraných částí Unicode
for (pismeno=0x00a0;pismeno<=0x024f;++pismeno) output(pismeno);
for (pismeno=0x1e00;pismeno<=0x1eff;++pismeno) output(pismeno);
for (pismeno=0x2c60;pismeno<=0x2c7f;++pismeno) output(pismeno);
putchar('\n');
*/

/*
https://en.wikipedia.org/wiki/Latin_script_in_Unicode

AaÀÁÂÃÄÅàáâãäåĀāĂ㥹ǍǎǞǟǠǡǺǻȀȁȂȃȦȧḀḁẚẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặⱥ
BbḂḃḄḅḆḇ
CcÇçĆćĈĉĊċČčƇƈḈḉ
DdĎďĐđƉƊḊḋḌḍḎḏḐḑḒḓ
EeÈÉÊËèéêëĒēĔĕĖėĘęĚěȄȅȆȇȨȩḔḕḖḗḘḙḚḛḜḝẸẹẺẻẼẽẾếỀềỂểỄễỆệ
FfƑƒḞḟẛẜẝ
GgĜĝĞğĠġĢģƓɠǤǥǦǧǴǵḠḡ
HhĤĥĦħȞȟḢḣḤḥḦḧḨḩḪḫẖⱧⱨ
IiÌÍÎÏìíîïĨĩĪīĬĭĮįİıIJijƖƗǏǐȈȉȊȋḬḭḮḯỈỉỊị
JjĴĵǰ
KkĶķĸƘƙǨǩḰḱḲḳḴḵⱩⱪ
LlĹĺĻļĽľĿŀŁłŁƚḶḷḸḹḺḻḼḽⱠⱡⱢ
MmḾḿṀṁṂṃ
NnÑñŃńŅņŇňʼnŊŋƝƞǸǹṄṅṆṇṈṉṊṋ
OoÒÓÔÕÖØòóôõöøŌōŎŏŐőŒœƠơǑǒǪǫǬǭǾǿȌȍȎȏȪȫȬȭȮȯȰȱṌṍṎṏṐṑṒṓỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ
PpṔṕṖṗⱣ
Qq
RrŔŕŖŗŘřȐȑȒȓṘṙṚṛṜṝṞṟⱤ
SsŚśŜŝŞşŠšȘșṠṡṢṣṤṥṦṧṨṩ
TtŢţŤťŦŧƫƬƭƮȚțṪṫṬṭṮṯṰṱẗⱦ
UuÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜȔȕȖȗṲṳṴṵṶṷṸṹṺṻỦủỨứỪừỬửỮữỤụỰự
VvṼṽṾṿⱱⱴ
WwŴŵẀẁẂẃẄẅẆẇẈẉⱲⱳẘ
XxẊẋẌẍ
YyÝŸýÿŶŷŸÿƳƴȲȳẎẏẙỲỳỴỵỶỷỸỹ
ZzƵƶŹźŻżŽžȤȥẐẑẒẓẔẕⱫⱬ
*/

/* výpis kódů znaků DEC/HEX/ZNAK
while ((pismeno=input())>0)
      {
      if (pismeno>' ') printf("%5d\t%04x\t",pismeno,pismeno);
      output(pismeno);
      putchar('\n');
      }
*/

/* výpis kódů znaků pro tabulku
while ((pismeno=input())>0)
      {
      if (pismeno>' ') printf("%d,",pismeno);
      else printf("0\n");
      }
*/

No, hádám že s těmi komentáři to nepotřebuje komentář, a zůstaly tam i pracovní pomůcky, zakomentované na konci kódu :lol:

Akorát to nejspíš bude správně pracovat jen v Linuxu a dalších moderních systémech, nevím jestli si maloměkká atrapa herní konzole nechá vnutit změnu kódování na UTF-8, v jiném to sice bude také fungovat, ale jenom s čistým ASCII (takže zkušební zprávu to přeloží!) A předem říkám že wchar nemám rád a nehodlám ho používat.

P.S. Najdete tam toho dinosaura? :twisted:
Nejhroznější sen linuxáka: nabootuje počítač, a tam Windows.
Nejhroznější sen windowsáka: nabootuje počítač, a tam Linux.
Nejkrásnější sen linuxáka: nabootuje počítač, a tam Linux.
Nejkrásnější sen windowsáka: nabootuje počítač.


  • Mohlo by vás zajímat
    Odpovědi
    Zobrazení
    Poslední příspěvek
  • Vigenerova šifra - C
    od popcorn » 17 zář 2017 09:26 » v Programování a tvorba webu
    38
    822
    od faraon
    24 zář 2017 07:39
  • Jakmile dohraju hru tak se ta hra sekne a nereaguje a potom nejde zapnout hra
    od Gargi10 » 27 srp 2017 19:53 » v Hry
    1
    150
    od popcorn
    27 srp 2017 20:09
  • Mála podpora na webu
    od Akrej » 20 lis 2016 16:08 » v Vše ostatní (Off topic)
    2
    366
    od Akrej
    18 pro 2016 18:58
  • malá skriňa za 30 000
    od alkyfans » 27 lis 2016 11:10 » v Rady s výběrem hardwaru a sestavením PC
    13
    581
    od vuLva
    03 pro 2016 14:40
  • Nefunkční hra
    od Dolpi » 08 srp 2017 12:04 » v Hry
    2
    165
    od Dolpi
    08 srp 2017 12:12

Zpět na “Programování a tvorba webu”

Kdo je online

Uživatelé prohlížející si toto fórum: CommonCrawl [Bot] a 0 hostů