Po drátě 6: Řešení úlohy č. 77
Co s tou ošklivou věcí? Podle úvodního řádku je vidět, že by to měl být script v perlu. Pokud odoláte pokušení zkoumat, co přesně dělá, a prostě jej spustíte, vysype se na vás chybové hlášení file descriptor 5 neni pripraven pro zapis!
Dobrá, tak mu jej otevřeme a rovnou přesměrujeme na standardní výstup, ať vidíme, co se děje:
$ ./potrubni_posta.pl 5>&1
Obratem se dozvíme, že prozměnu file descriptor 6 neni pripraven pro cteni! Dobra, pridame dalsi presmerovani:
$ ./potrubni_posta.pl 5>&1 6<&0
Teď vidíme, že program vyspal na výstup řetězec ymozaujkdlrrsltpwfgnhj. To nevypadá jako správné heslo. Ale my jsme přeci také přesměrovali standardní vstup na fd 6, a teď to vypadá, že script tam očekává nějaká data. Pokud mu vrátíme zpátky jeho výstup, dostaneme další odpověď: rtefzopiqwwxqyubklsmo. Při dostatečné trpělivosti takto můžeme dojít až ke správnému heslu, u kterého program skončí.
Nicméně nudnou práci má přece dělat počítač … Tak zkusíme spojit fd 5 a 6 přes rouru, když nám to napovídá i text k úloze. Intuitivní řešení v bashi
$ mkfifo roura $ ./potrubni_posta.pl 5>roura 6<roura
ale nebude fungovat, protože snaha o otevření FIFO pro zápis blokuje, dokud není otevřeno i pro čtení.
To můžeme vyřešit buďto tak, že na pozadí otevřeme FIFO pro čtení nějakým procesem, který z něj žádná data nečte:
$ mkfifo roura $ sleep 1 <roura & ./potrubni_posta.pl 5>roura 6<roura
anebo přesměrování u file descriptoru 5 nahradíme za read-write:
$ mkfifo roura $ ./potrubni_posta.pl 5<>roura 6<roura
Tak jako tak se na výstupu dozvíme, že heslo je krabice.
Zajímavosti
Zdrojový kód jsme se snažili udělat natolik ošklivý, aby jej hráči neměli sklony analyzovat (pro podobné účely je Perl jazyk neomezených možností :)), ale raději zkusili, co program dělá. Jak se můžete dočíst v diskuzi, tenhle záměr se tak úplně nepovedl.
Nápad na úlohu vznikl na některé ze schůzek, původně inspirován hrou Pipe Mania. Konkrétní implementaci v perlu zprasil Marble.
upravil jsem si oba fd
open(B, ">&=STDOUT") or E(1,5);
open(A, "<&=STDIN") or E(0,6);
pak to spustil zadal komplet abecedu:
./potrubni_posta.pl
Heslo je:
ymozaujkdlrrsltpwfgnhj
abcdefghijklmnopqrstuvwxyz
ijklmnopqrstuvwxyzabcdefg
Vypadla cela abeceda bez H posunuta o 7 zpet. To nebude nahoda, takze jsem zposunoval ymozaujkdlrrsltpwfgnhj preventivne o vsech 25 moznosti a reseni neslo prehlednout: "thjuvpefygmmngokrabice"