Dvigubas kodavimas

UŽDUOTIS

Modernus kodavimo standartas (MKS) pateikė naują algoritmą. Algoritmas dirba su trimis blokais, kiekvienas kurių sudarytas iš 128 bitų. Duotas blokas p (pradinis tekstas) ir raktinis blokas k. MKS kodavimo funkcija E grąžina užkoduotą bloką c:

c = E(p, k) .

Funkcijai E atvirkščia yra dekodavimo funkcija D:

D ( E(p, k), k ) = p ,     E ( D(c, k), k ) = c .

Naudojant dvigubą MKS kodavimą, paeiliui naudojami du nepriklausomi raktiniai blokai k1 ir k2. Pirmiau taikomas raktas k1, paskui k2:

   c2 = E ( E(p, k1), k2 ).

Taip pat duotas sveikasis skaičius s, kuris nusako raktinių blokų struktūrą: reikšminiai yra tik kairiausi 4*s bitų, tuo tarpu likusieji (dešiniausi 128–4*s) bitai yra lygūs 0. Skaičius s yra tas pats abiem raktams.

Jums duotas pradinis tekstas p, jį atitinkantis dvigubai užkoduotas tekstas c2, bei raktinių blokų struktūra, kurią nusako sveikasis skaičius s. Raskite kodavimo raktų (t.y blokų) porą, kuri buvo panaudota pranešimui užkoduoti. 

Kodavimo ir dekodavimo algoritmai pateikti bibliotekoje. 
Jūs turite pateikti tik surastus raktinius blokus. Programos pateikti nereikia. 

PRADINIAI DUOMENYS

Dešimt pradinių duomenų rinkinių duoti tekstinėse bylose, pavadintose vardais nuo double1.in iki double10.in. Kiekvieną bylą sudaro trys eilutės. Pirmoje eilutėje įrašytas sveikasis skaičius s, antroje – pradinis blokas p, o trečioje – dvigubai užkoduotas blokas c2. Abu blokai pateikti 32 šešioliktainių skaitmenų ('0'..'9', 'A'..'F') eilutėmis. Bibliotekoje numatyta galimybė eilutes paversti blokais. Pradiniai duomenys tokie, kad sprendinys egzistuoja. 

REZULTATAI

Jums reikia pateikti dešimt rezultatų bylų, atitinkančių pradines bylas. Kiekvieną rezultatų bylą turi sudaryti trys eilutės. Pirmoje eilutėje turi būti įrašytas tekstas:
#FILE double I
čia I yra atitinkamos pradinių duomenų bylos numeris. Antroje eilutėje pateikiamas raktinis blokas k1, trečioje eilutėje pateikiamas raktinis blokas k2. Raktiniai blokai turi būti tokie, kad galiotų lygybė:

   c2 = E ( E(p, k1), k2 ).

Abu blokai turi būti užrašyti 32 šešioliktainių skaitmenų ('0'..'9', 'A'..'F') eilutėmis. Bibliotekoje numatyta galimybė blokus paversti eilutėmis. Jeigu galimi keli sprendiniai, reikia pateikti vieną iš jų.

PAVYZDYS

Pateiktam pavyzdžiui naudojama byla, kurios numeris yra 0. 

double0.in				Galima rezultatų byla

#FILE double 0
A0000000000000000000000000000000
70000000000000000000000000000000

1
00112233445566778899AABBCCDDEEFF
6323B4A5BC16C479ED6D94F5B58FF0C2

BIBLIOTEKA

FreePascal biblioteka	(Linux: aeslibp.p, aeslibp.ppu, aeslibp.o;
Windows: aeslibp.p, aeslibp.ppw, aeslibp.ow):

type
  HexStr = String [ 32 ]; { only '0'..'9', 'A'..'F' }
  Block  = array [ 0..15 ] of Byte; { 128 bits }

procedure HexStrToBlock ( const hs: HexStr; var b: Block );
procedure BlockToHexStr ( const b: Block; var hs: HexStr );
procedure Encrypt ( const p, k: Block; var c: Block );
  { c = E(p,k) }
procedure Decrypt ( const c, k: Block; var p: Block );
  { p = D(c,k) }

Programa aestoolp iliustruoja, kaip naudotis FreePascal’io biblioteka.

RIBOJIMAI

Skaičiui s galioja: 1  s  5. Atkreipiame dėmesį, kad skaičius s lygus rakto reikšminių šešioliktainių skaitmenų skaičiui.

UŽUOMINA

Gera programa gali surasti abu raktus bet kuriam pateiktam pradinių duomenų rinkiniui per mažiau nei 10 sekundžių.