Prog2
A jelen harmadik laborgyakorlat reguláris része a közös http://www.inf.unideb.hu/~nbatfai/kp2/Kozos_Prog2_feladatok_BN_2012osz.pdf hozzájárulásunk 9. feladata az EXOR törés. Ez szokás szerint prog1-beli feladat, amelyet most Java-ban kell implementálnunk. Vegyük észre, hogy sokaknak gond nélkül ment a C, C++ kódok Java átírása... miért? Egyrészt, mert ügyesek természetesen, másrészt mert a C és a Java változó, kifejezés fogalmai megegyeznek; azaz szinte nem volt mit tanulni, csak élvezni az átírást.
1. lépés
A prog1-es http://progpater.blog.hu/2011/02/15/felvetelt_hirdet_a_cia poszt alapján C vagy Java programmal valósítsuk meg egy tetszöleges tiszta szöveg kódolását/dekódolását. (Az első 3-nak 2 trófea Java, 2 trófea az esetleges C implementációért). A Java implementáció itt található: http://www.tankonyvtar.hu/hu/tartalom/tkt/javat-tanitok-javat/ch01.html, lap közepén a "1.12. példa - Titkosítás kizáró vaggyal" pontban, az ExorTitkosító osztályról van szó (aki nem hozzám járt, nem ismeri az EXOR-os titkosítást, annak kötelező elolvasni a Javát tanítok ezen példáját).
2. lépés
Magam is futtattam ezt a progit és az alábbi titkosított szöveget készítettem el 8 betűs számokból álló titkos kulccsal: http://www.inf.unideb.hu/~nbatfai/2012osz.titkos1 Mi a tiszta szöveg? Törd meg a saját progiddal ezt a kódot!
3. lépés
A törésed, segítségül használd a korábbi http://progpater.blog.hu/2011/02/15/felvetelt_hirdet_a_cia poszt C implementációját, vagy az ugyanerről szóló, de 1 évvel későbbi labor posztját: http://progpater.blog.hu/2012/02/25/de_ik_prog_labor_labdarugo_bajnoksag_es_kupa 5 trófea az első három sikeres törőnek (mi a tiszta szöveg és mi a pontos kulcs a kérdés).
Mentőmellény: akinek az ékezetek miatt gondja támad, egyrészt: http://progpater.blog.hu/2011/09/16/nem_mindig_a_jobbik_csapat_nyer/fullcommentlist/1#c14487806
vagy gedit ExorTitkosító.java bemásolása után:
[norbert@matrica EXOR]$ javac -encoding UTF-8 ExorTitkosító.java
[norbert@matrica EXOR]$ java ExorTitkosító kulcs <tiszta.txt >titkos.bin
[norbert@matrica 3]$ javac ExorToro.java
[norbert@matrica 3]$ time java ExorToro <2012osz.titkos1
00009999Mi indulunk, ha kell
Mi nem felejtjük el, hogy
Bennünk a vér piros-fehér
Mi küzdünk haver
Ha kell bárkivel
Mert a győzelem mindennél többet ér
...
A LOKIÉ!!!
real 0m1.675s
user 0m1.681s
sys 0m0.080s
/* * Első nekifutás: formális átírás (kommentezve este lesz a blogon) 2012. okt. * 2. Bátfai Norbert */ public class ExorToro { // Néhány konstans (ezek az átírandó C kód örökségei). /** * Max. mekkora lehet a kezelt titkosított rész. */ public static final int MAX_TITKOS = 65535; /** * Bufferelten olvasunk, (ez az átírandó C kód öröksége). */ public static final int OLVASAS_BUFFER = 256; /** * Dupla PIN méretű a kulcs. */ public static final int KULCS_MERET = 8; /* * Ahogy C-ben is, most is bájttömbökkel dolgozunk alapvetően, ez is * egyértelműen a C árírata. */ /** * A kulcsot tárolja. */ byte[] kulcs = new byte[KULCS_MERET]; /** * A titkos szöveget tárolja. */ byte[] titkos = new byte[MAX_TITKOS]; /** * A titkosból előállított szöveget tárolja. */ byte[] tiszta = new byte[MAX_TITKOS]; /* * Bár a Java tömb már tudja a saját méretét, de most a titkos buffer nyilván * nagyobb, ezért tároljuk ebben, hogy mennyi is valójában a beolvasott titkos * szöveg mérete. */ int titkosMeret; /* * Hová írjuk majd az eredményt? Erre a csatornára. (Ez a Javát tanítokos * példa öröksége.) */ java.io.OutputStream kimenőCsatorna; /** Az <code>ExorToro</code> objektum elkészítése. */ public ExorToro(java.io.InputStream bejövőCsatorna, java.io.OutputStream kimenőCsatorna) /* * Az IO problémás dolog, ezzel jelezzük a hívónak, hogy ilyen * kivételt dobhatunk az ExotToro létrehozásakor, mert a kivétellel a * konstruktorban nem foglalkozunk, azok értelmes kezelését a hívóra * bízzuk. */ throws java.io.IOException { // Beállítjuk, hová írjuk majd az eredményt this.kimenőCsatorna = kimenőCsatorna; // Ebbe a bufferbe olvasunk majd a bejövő csatornáról. byte[] buffer = new byte[OLVASAS_BUFFER]; // Mennyit olvasunk a bejövő csatornáról? int olvasottBajtok; // Hol tart a bufferelt olvasás? int titkosIndex = 0; // titkos fajt berantasa, a C mintájára, de lényegesen egyszerűsítve, hiszen nincs mutató léptetés while ((olvasottBajtok = bejövőCsatorna.read(buffer, 0, OLVASAS_BUFFER)) != -1) { // System.arraycopy: olvas el az API doksit! if (titkosIndex + olvasottBajtok < MAX_TITKOS) { System.arraycopy(buffer, 0, titkos, titkosIndex, olvasottBajtok); // Hol tart a bufferelt olvasás? titkosIndex += olvasottBajtok; } else { System.arraycopy(buffer, 0, titkos, titkosIndex, MAX_TITKOS - titkosIndex); // Hol tart a bufferelt olvasás? titkosIndex += (MAX_TITKOS - titkosIndex); break; } } // Mennyi titkos szöveget dolgozunk fel: titkosMeret = titkosIndex; // A C kódban az str-es függvények helyes működéséhez kellett a \0 // ennek öröksége csal ez a ciklus for (int i = 0; i < MAX_TITKOS - titkosIndex; ++i) { tiszta[titkosIndex + i] = titkos[titkosIndex + i] = '\0'; } // Így tesztelheted, hogy mit is olvastál be: // (érdemes olvasható szöveggel tesztelni a beolvasást) // System.out.println(new String(titkos)); } public void tores() throws java.io.IOException { byte[] jegyek = new byte[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; // A C kódból átmósolt ciklus a fenti jegyekre átírva: // osszes kulcs eloallitasa for (int ii = 0; ii <= 9; ++ii) { for (int ji = 0; ji <= 9; ++ji) { for (int ki = 0; ki <= 9; ++ki) { for (int li = 0; li <= 9; ++li) { for (int mi = 0; mi <= 9; ++mi) { for (int ni = 0; ni <= 9; ++ni) { for (int oi = 0; oi <= 9; ++oi) { for (int pi = 0; pi <= 9; ++pi) { // végigzongorázzuk az összes kulcsot, ezért Brute Force jellegű a törés. kulcs[0] = jegyek[ii]; kulcs[1] = jegyek[ji]; kulcs[2] = jegyek[ki]; kulcs[3] = jegyek[li]; kulcs[4] = jegyek[mi]; kulcs[5] = jegyek[ni]; kulcs[6] = jegyek[oi]; kulcs[7] = jegyek[pi]; if (exor()) { kimenőCsatorna.write(kulcs, 0, KULCS_MERET); kimenőCsatorna.write(tiszta, 0, titkosMeret); // Csúnya itt, de gyorsan kíratom a time paranccsal futtatva // a szükséges időt majd. System.exit(0); } } } } } } } } } } /** Másolva a C kódból, a típuskényszerítés kellett (de különben le sem fordul). */ public boolean exor() { int kulcs_index = 0; for (int i = 0; i < titkosMeret; ++i) { tiszta[i] = (byte) (titkos[i] ^ kulcs[kulcs_index]); kulcs_index = (kulcs_index + 1) % KULCS_MERET; } return tiszta_lehet(); } // A C kódból: public boolean tiszta_lehet() { // a tiszta szoveg valszeg tartalmazza a gyakori magyar szavakat // illetve az átlagos szóhossz vizsgálatával csökkentjük a // potenciális töréseket double szohossz = atlagosSzohossz(); String tisztaStr = new String(tiszta); return szohossz > 6.0 && szohossz < 9.0 && (tisztaStr.indexOf("hogy") != -1) && (tisztaStr.indexOf("nem") != -1); } // A C kódból: public double atlagosSzohossz() { int sz = 0; for (int i = 0; i < titkosMeret; ++i) { if (tiszta[i] == ' ') { ++sz; } } if (sz > 0) { return (double) titkosMeret / (double) sz; } else { // egy szó sem volt benne: return Double.MAX_VALUE; } } public static void main(String[] args) { try { // Elkészítjük a törő objektumot (amely most a sztenderd inputról olvassa a // titkos szöveget és a sztenderd kimenetre írja az eredményt) majd meg is // kérjük, hogy hajtsa végre a törést: new ExorToro(System.in, System.out).tores(); } catch (java.io.IOException e) { // Ha volt kivétel kiírjuk a hívási láncot (a lényeg, hogy nem nyeljük le :) e.printStackTrace(); } } /* * Az itteni kód egy része a konstruktorba, másik része a tores() módszerbe * kerül majd. int main (void) { * * char kulcs[KULCS_MERET]; char titkos[MAX_TITKOS]; char *p = titkos; int * olvasott_bajtok; * * // titkos fajt berantasa while ((olvasott_bajtok = read (0, (void *) p, (p * - titkos + OLVASAS_BUFFER < MAX_TITKOS) ? OLVASAS_BUFFER : titkos + * MAX_TITKOS - p))) p += olvasott_bajtok; * * // maradek hely nullazasa a titkos bufferben for (int i = 0; i < * MAX_TITKOS - (p - titkos); ++i) titkos[p - titkos + i] = '\0'; * *...*/ }
Kick-off
Sokaknak ezek a feladatok nem kihívások abban az értelemben, hogy vagy eleve hozzák a megoldást, vagy gyorsan elkészítik, íme nekik szólhat a labor nem reguláris feladata.
Feladat: az alábbi Java kód mintájára készítsük el a jelen bajnokság minden csapatának hasonló kartonját! Egy kartonért adok 6 trófeát. A bemenő mérkőzés adatokat az MLSZ megfelelő lapjairól tudod leolvasni.
/* GoalIntensity.java 2012. szept. 27. */ package goalintensity; /** * Kísérletek a gól intenzitás környékén. * (A gól intenzitás fogalma kapcsán lásd a John Wesson (2002) The Science of Soccer isbn 0750308133 könyvet.) * * @author Norbert Bátfai * @version 0.0.1 */ public class GoalIntensity { /** * A 2012/13 bajnokság kezdetétől pozitív percben a lőtt gól, negatívban a * kapott. Ezeket az adatokat az MLSZ adatbankjából tudod kikattintgatni: * http://adatbank.mlsz.hu/foprog.asp?menu=p00_0001&p_evad=11&p_szervezet=24&p_verseny_id=9593 */ int[] goals = { /* 8 SIDIBE IBRAHIMA 10 SZAKÁLY PÉTER 26 SIDIBE IBRAHIMA 45 KULCSÁR TAMÁS -11 ANDRIC NEMANJA ... */ 8, 10, 26, 45, -11, -117, 2 * 90 + 23, 2 * 90 + 73, -233, -317, -330, 3 * 90 + 70, 3 * 90 + 74, 3 * 90 + 79, 4 * 90 + 77, 6 * 90 + 5, 6 * 90 + 8, 6 * 90 + 53, 6 * 90 + 64, -561, -686 }; public void eredoEs60asAblak(int f) { int eredo[] = new int[f * 90]; int golInt[] = new int[f * 90]; int meccsEredmeny[] = new int[f * 90]; // A defenzív taktika: for (int i = 0; i < eredo.length; ++i) { eredo[i] = golInt[i] = meccsEredmeny[i] = 0; } // Elhelyezzük az "idővonalakon" (most az első 8 forduló percben), hol estek a gólok for (int i = 0; i < goals.length; ++i) { if (goals[i] < 0) { eredo[Math.abs(goals[i])] = meccsEredmeny[Math.abs(goals[i])] = -1; } if (goals[i] > 0) { eredo[goals[i]] = meccsEredmeny[goals[i]] = 1; } } int gyujto = 0, gyeredo = 0; for (int i = 0; i < eredo.length; ++i) { gyeredo += eredo[i]; eredo[i] = gyeredo; // A golInt idővonalát úgy vizsgáljuk, hogy csak // az utolsó 60 perc számít, de amúgy úgy kezeljük, mint az eredo-t: if (i < 60) { gyujto += meccsEredmeny[i]; golInt[i] = gyujto; } else { gyujto = 0; for (int j = i - 60; j < i; ++j) { gyujto += meccsEredmeny[j]; golInt[i] = gyujto; } } } // A 3 kapott görbe kiíratása for (int i = 0; i < eredo.length; ++i) { System.out.println(i + " " + golInt[i] + " " + meccsEredmeny[i] + " " + eredo[i]); } } /* Használat (most ugye a szereplő DVSC-re) - ennek az osztálynak a kimenetét nyomd át a data60dvsc nevű fájlba, majd - $ R --slave --vanilla <dispdata60dvsc.r ahol a dispdata60dvsc.r R szkript a következő: # dispdata60dvsc.r # 2012. szept. 27. # Norbert Bátfai # Kísérletek a gól intenzitás környékén. # (A gól intenzitás fogalma kapcsán lásd a John Wesson (2002) The Science of Soccer isbn 0750308133 könyvet.) # A GoalIntensity kimenetének ábrázolása attach(mtcars) par(mfrow=c(3,1)) adatok<-read.table("data60dvsc") x <- adatok$V1 y <- adatok$V2 v <- adatok$V3 z <- adatok$V4 plot(x,y, main = "DVSC \"klasszikus\" golintenzitas", sub="2012/13 1-8ford. [60 perces ablakok]x[eredo db]", xlab="perc", ylab="eredo golok szama/60 elozo perc") for(i in seq(from=0,to=8*90,by=90)) abline(v=i, col = "gold", lwd = 2) plot(x,v, main = "DVSC lott es kapott golok ideje, arannyal a meccsek", sub="2012/13 1-8ford. [mikor]x[kapott=-1,lott=1]", xlab="perc", ylab="golok") for(i in seq(from=0,to=8*90,by=90)) abline(v=i, col = "gold", lwd = 2) plot(x,z, main = "DVSC lott es kapott golok az ido fuggvenyeben", sub="2012/13 1-8ford. [perc]x[db]", xlab="perc", ylab="golok eredoje") for(i in seq(from=0,to=8*90,by=90)) abline(v=i, col = "gold", lwd = 2) */ public static void main(String[] args) { new GoalIntensity().eredoEs60asAblak(8); } }
(A fenti grafikonokat kell kapnod pdf-ben.)
PLB, PLK
A tavalyi labor mintájára idén is megrendeznénk a bajnokságot és a kupát a kurzusban. Most egy győzelemért 7, egy döntetlenért 4, egy vereségért 2 trófeát adnék (+ extra trófeák az első háromnak a végén), de a pontos számok tekintetében szükségem lenne arra az infóra, hogy hány csapat lenne. Ezért egy kommentben jelezzük a csapatnevet (amely max. két hallgatót takarhat) amellyel neveznénk ezekre az említett tornákra (egy "lájtosított környezetben" megy majd mindkét torna.)
Java esettan.
A forrásokat beszéljük át és a Városi Hangyát teszteljük az LG és a MOTO készüléken.
http://www.inf.unideb.hu/~nbatfai/konyvek/MOBP/mobp.book.xml.html#id465627
Ne feledd, hogy ne a debug release-t töltsd a készülékre, hanem kövesd a fenti linket.