Diszkre t matematika 8. elo ada s MA RTON Gyo ngyve r mgyongyi@ms.sapientia.ro Sapientia Egyetem, Matematika-Informatika Tansze k Marosva sa rhely, Roma nia 2018, o szi fe le v MA RTON Gyo ngyve r 2018, Diszkre t matematika
Miről volt szó az elmúlt előadáson? Kódolási technikák az ASCII, az Unicode kódok a base64 kódolási technika az index metódus az ord, chr függvények a random könyvtárcsomag műveletek bináris számrendszerben bitműveletek bináris, szöveg-állományok, feladatok Python stringek, az encode, decode függvények
Miről lesz szó? a base64 kódolási technika Számelmélet prímszámok, alapfogalmak prímtesztelő algoritmusok kongruenciák
A base64 kódolás base64 kódolás esetén a kimenetet 64 karakteren ábrázoljuk a 64 + 1 karakter (26 + 26 + 10 + 2 + 1): ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= az algoritmus a bementi bájtsorozat minden 3 bájtjából 4 bájtot hoz létre = karakternek speciális szerepe van, a kódolt adatsor végére kerül és azt jelzi, hogy a bemeneti bájtsorozat 3-al való osztási maradéka 1 vagy 2. Pythonban a base64 könyvtárcsomagot kell importálni: b64encode lesz a kódoló függvény, b64decode lesz a dekódoló függvény
A base64 kódolás Python példák: import base64 >>> base64.b64encode( Sapientia.encode()) b U2FwaWVudGlh >>> base64.b64encode( Sap.encode()) b U2Fw >>> base64.b64encode( Sapi.encode()) b U2FwaQ== >>> base64.b64encode( Sapie.encode()).decode() b U2FwaWU= >>> base64.b64decode( U2FwaWVudGlh ) b Sapientia
A Sapi szó base64 kódolása >>> ABC64= ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= >>> print (ord( S ), ord( a ), ord( p ), ord( i )) 83 97 112 105 >>> print (ABC64[20], ABC64[54], ABC64[5], ABC64[48]) U 2 F w >>> print (ABC64[26], ABC64[16]) a Q
A Sapi szó base64 kódolása >>> format((83 & 0xFC) >> 2, b ) 10100 >>> format((83 & 0x03) << 4, b ) 110000 >>> format((97 & 0xF0) >> 4, b ) 110 >>> format((97 & 0x0F) << 2, b ) 100 >>> format((112 & 0xC0) >> 6, b ) 1 >>> format((112 & 0x3F), b ) 110000
A base64 kódolás 1. feladat Az alábbi Python függvény meghatározza a paraméterként megadott mstr karakterlánc base64-es alakját, a kimenet típusa szintén karakterlánc. def myb64encode(mstr): enstr = n = len(mstr) for i in range (0, n, 3): b = (mstr[i] & 0xFC) >> 2 enstr += ABC64[b] b = (mstr[i] & 0x03) << 4 if i + 1 < n: b = b ( (mstr[i + 1] & 0xF0) >> 4 ) enstr += ABC64[b] b = ( mstr[i + 1] & 0x0F) << 2 if i + 2 < n: b = b ( ( mstr[i+2] & 0xC0) >> 6 ) enstr += ABC64[b] b = mstr[i + 2] & 0x3F enstr += ABC64[b] else: enstr += ABC64[b] enstr += = else: enstr += ABC64[b] enstr += == return enstr
A base64 kódolás 2. feladat Az alábbi Python függvény meghatározza a base64-es formában megadott bemeneti paraméter eredeti alakját. def myb64decode(enstr): destr = [] n = len(enstr) for i in range(0, n, 4): b0 = ABC64.index(enStr[i]) b1 = ABC64.index(enStr[i + 1]) b2 = ABC64.index(enStr[i + 2]) b3 = ABC64.index(enStr[i + 3]) temp = ((b0 << 2) (b1 >> 4)) & 255 destr += [temp] if b2 < 64: temp = ((b1 << 4) (b2 >> 2)) & 255 destr += [temp] if b3 < 64: temp = ((b2 << 6) b3) & 255 destr += [temp] return bytes(destr) >>> myb64encode( műszaki egyetem.encode()) >>> myb64decode( bco7c3pha2kgzwd5zxrlbq== ).decode() műszaki egyetem
Számelmélet Témakörök: oszthatóság, legnagyobb közös osztó prímszámok, prímtesztelő algoritmusok moduláris aritmetika, maradékosztás generátor elem, diszkrét logaritmus prímfaktorizáció diofantikus egyenletek, kínai maradéktétel alkalmazások: Diffie-Hellman kulcscsere, RSA kulcscsere
Prímszámok 1. tétel Prímszámok: azok az 1-nél nagyobb egész számok, amelyek nem oszthatóak, csak 1-el és önmagukkal. Összetett számok: azok az 1-nél nagyobb egész számok, amelyek nem prímszámok. Minden 1-nél nagyobb pozitív egész számnak van egy prímosztója. A bizonyítás indirekt bizonyítási módszerrel történik: tegyük fel az ellenkezőjét, azaz létezik egy olyan szám amelyiknek nincs prímosztója; ezek a számok meghatároznak egy nem üres halmazt. A természetes számok jólrendzettség tulajdonsága alapján ebben a halmazban van egy legkisebb ilyen elem, legyen ez n. Mivel n-nek nincs primosztója, de n osztja n-t, következik, hogy n nem prímszám. Azaz feĺırható: n = a b, ahol 1 < a < n, 1 < b < n. Mivel a < n következik, hogy a-nak van primosztója. De a bármely osztója osztja n-t, ez pedig ellentmondás.
Prímszámok 2. tétel Végtelen sok prímszám létezik. Egyik bizonyítási módszer Eukleidész, Elemek című könyvében található: feltételezzük, hogy a prímszámok halmaza véges. Jelöljük ennek a halmaznak az elemeit p 1, p 2,..., p n-nel. Jelöljük Q = p 1 p 2... p n + 1. Bebizonyítható, hogy Q-nak viszont van egy olyan prímosztója amelyik nem szerepel a fenti halmazban. Feltételezzük az ellenkezőjét: azaz legyen q, Q egy osztója, és feltételezzük, hogy ez megegyezik valamelyik p j -vel. Ez azonban azt jelenti hogy q osztja Q p 1 p 2... p n = 1, azaz 1-t. Ez ellentmondás, mert egy prímszám nem oszthatja az 1-et. Pl. Ha összeszorozzuk az első 6 prímszámot, akkor kapunk egy olyan számot, amelynek biztosan lesz egy új prímszám osztója: 2 3 5 7 11 13 + 1 = 30031 = 59 509 pl. Hendrik Lenstra: Végtelen sok összetett szám létezik. Ahhoz, hogy egy új összetett számot kapjunk szorozzuk össze az első n összetett számot és ne adjunk hozzá 1-et.
Prímszámok 3. tétel Ha n egy összetett szám, akkor n-nek van egy olyan prímosztója, amelyik kisebb vagy egyenlő mint n. Bizonyítása a 1. tétel alapján történik. Ha n összetett, akkor n = a b, ahol 1 < a b < n. Fenn kell álljon, hogy a n, mert másképp n < a b n = n n < a b. Az 1. tétel alapján a-nak van egy prímosztója, amelyik n-nek is prímosztója, amelyik tehát n. A tétel alapján algoritmusok adhatóak meg a prímszámok vizsgálatára: osztási próba módszere (trial division): egy adott szám vizsgálata, Eratosztenész szitája: meghatározza egy adott n-ig az összes prímszámot, hatékonyabb algoritmusok: Miller-Rabin prímteszt, Solovay-Strassen prímteszt, AKS prímteszt, stb.
Prímtesztelő algoritmusok Rossz hatékonyságú algoritmus: meghatározzuk egy szám osztóinak számát, ha az egyenlő kettővel akkor prímszám, másképp nem prímszám. Osztási próba módszere (trial division): sorra próbáljuk a páratlan számokkal való oszthatóságot. Az első osztónál leáll az algoritmus, azzal a kimenettel, hogy a szám nem prímszám. Ha a tesztelő szám négyzetgyökéig nem találunk osztót, akkor a szám prímszám. Eratosztenész szitája: kizárásos módszerrel adott n-ig meghatározzuk a prímszámok listáját Miller-Rabin prímteszt: egy adott páratlan számról biztosan megtudja állapítani, hogy az összetett, az azonban csak nagyon nagy valószínűséggel fogadható el, hogy a szám prím. A gyakorlatban nagyon fontos feladat eldönteni egy nagy (több mint 300 számjegyű) számról hogy prímszám-e vagy sem.
Az osztási próba módszere Vizsgáljuk meg az osztási próba módszerével, hogy 101 prímszám-e: a cél: minél kevesebb osztást végezzünk az oszthatóság eldöntéséhez, a 11-el már nem kell megvizsgálni az oszthatóságot, mert 11 11 = 121 > 101, vagy 101 < 11 milyen számokkal vizsgáljuk az oszthatóságot? csak a páratlan számokkal vizsgáljuk az oszthatóságot, mert a 2-nél nagyobb prímszámoknak nem lehet páros osztójuk, 101 nem osztható 3, 5, 7, 9 101 prímszám.
Az osztási próba módszere 3. feladat Írjunk Python függvényt, amely megvizsgálja az osztási próba módszerével, hogy n prímszám-e. def triald1(n): if n == 2: return True if n % 2 == 0: return False i = 3 while i*i <= n: if n % i == 0: return False i += 2 return True def triald2(n): i = 3 while i*i <= n: if n % i == 0: return False i += 2 return True Ha bemenetnek csak páratlan számot adhatunk, akkor a triald2(n) függvénnyel dolgozunk.
Eratosztenész szitája Eratosztenész szitájával határozzuk meg 100-ig a prímszámokat: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Eratosztenész szitája Kivettük az 1-et és a 2-vel osztható számokat, a 2 marad: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Eratosztenész szitája Kivettük a 3-mal osztható számokat is, a 3 marad: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Eratosztenész szitája Kivettük az 5-tel osztható számokat is, az 5 marad: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Eratosztenész szitája Kivettük a 7-tel osztható számokat is, a 7 marad: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Eratosztenész szitája Összesen marad 25, 1-nél nagyobb szám, ezek a 100-nál kisebb prímszámok: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Eratosztenész szitája 4. feladat Eratosztenész szitájának módszerével kíıratjuk n-ig a prímszámokat. def erat(n): L = [True] * n L[0] = L[1] = False for i in range (2, n): if L[i] == True: print(i, end =, ), for j in range(i*i, n, i): L[j] = False
Eratosztenész szitája 5. feladat Eratosztenész szitájának módszerével létrehozzunk egy listát, amely tartalmazza n-ig a prímszámokat. def eratl(n): L = [True] * n L[0] = L[1] = False Lp = [] for i in range (2, n): if L[i] == True: Lp += [i] for j in range (i*i, n, i): L[j] = False return Lp
Eratosztenész szitája 6. feladat Eratosztenész szitájának módszerével létrehozzunk egy listát, amely tartalmazza n-ig a prímszámokat. Csak a páratlan számok felett végezzük a vizsgálódást. def eratl_(n): L = [True] * n L[0] = L[1] = False Lp = [2] for i in range (3, n, 2): if L[i] == True: Lp += [i] for j in range (i*i, n, i): L[j] = False return Lp
Kongruenciák a számelmélet alapjait képezik, amelyet Gauss dolgozott ki, a 19. században megjelenik a mindennapi életben: az órák (mod 12) vagy (mod 24) szerint, az év (mod 7) szerint működik, stb. legyen m egy pozitív egész szám; azt mondjuk, hogy a kongruens b-vel modulo m szerint, ha m (a b); ezt a b (mod m)-el jelöljük; ellenkező esetben azt mondjuk, hogy a inkongruens b-vel modulo m szerint átalakítva egyenletté: a b (mod m) akkor és csakis akkor, ha létezik egy k egész szám, úgy hogy: a = b + km a x b (mod m) típusú egyenletek megoldásából indulunk ki, ahol a (mod m), m-mel való osztási maradékot jelöl
Kongruenciák Példák: 21 3 (mod 9), mert 9 (21 3), hasonlóan: 4 5 (mod 9) és 79 7 (mod 9) 14 5 (mod 12), mert 12 (14 5) = 9 21 3 (mod 9) 21 = 3 + 2 9 alkalmazási terület: prímtesztelő algoritmusok, adatbiztonság, kódelmélet Feladat: határozzuk meg azt az x számot amelyre fennáll: 3 x 14 (mod 19), naiv megoldás: x helyébe rendre 1, 2,... 18 értékeket helyettesítve megvizsgálom mikor áll fenn az egyenlőség, tudunk-e jobbat?
Kongruenciák Alaptulajdonságok reflexív: ha a egy egész szám, akkor a a (mod m), szimmetrikus: ha a, b egész számok és a b (mod m), akkor b a (mod m), tranzitív: ha a, b, c egész számok és a b (mod m), b c (mod m), akkor a c (mod m), Aritmetikai műveletekkel kapcsolatos tulajdonságok: legyenek a, b, c, m egész számok, ahol m > 0 és a b (mod m). Ekkor fennállnak a következők: a + c b + c (mod m), a c b c (mod m), a c b c (mod m), Az osztás műveletére nem adhatunk analóg tulajdonságot.
Kongruenciák Az osztással kapcsolatos tulajdonság: Példák: Legyenek a, b, c, m egész számok, ahol m > 0, d = lnko(c, m) és a c b c (mod m). Ekkor fennáll: a b (mod m/d). Legyen 14 8 (mod 6) A kongruenciát nem tudjuk végigosztani 2-vel, mert nem igaz az, hogy 7 4 (mod 6). A kongruenciát végigtudjuk osztani úgy 2-vel, hogy osztjuk a modulust is 2-vel, mert igaz, hogy lnko(2, 6) = 2, azaz fennáll: 7 4 (mod 3) Legyen 42 77 (mod 5) A kongruenciát végig tudjuk osztani 7-tel, úgy hogy osztjuk a modulust 1-el, mert igaz, hogy lnko(7, 5) = 1, azaz fennáll: 6 11 (mod 5)
Kongruenciák Az osztással kapcsolatos tulajdonság: Példák: Legyen 50 20 (mod 15) A kongruenciát nem tudjuk végigosztani 10-zel, mert nem igaz az, hogy 5 2 (mod 15). A kongruenciát végig tudjuk osztani úgy 10-zel, hogy osztjuk a modulust is 5-tel, mert igaz, hogy lnko(10, 15) = 5, azaz fennáll: 5 2 (mod 3) A kongruenciát végig tudjuk osztani úgy 5-tel, hogy osztjuk a modulust is 5-tel, mert igaz, hogy lnko(5, 15) = 5, azaz fennáll: 10 4 (mod 3)
Kongruenciák További tulajdonságok: legyenek a, b, c, d, m egész számok, ahol m > 0, a b (mod m) és c d (mod m). Ekkor fennállnak a következők: a + c b + d (mod m), a c b d (mod m), a c b d (mod m), a n b n (mod m), ahol n pozitív egész szám.