Diszkrét matematika 7. előadás mgyongyi@ms.sapientia.ro Sapientia Egyetem, Matematika-Informatika Tanszék Marosvásárhely, Románia 2018, őszi félév
Miről volt szó az elmúlt előadáson? számrendszerek számrendszerek közötti átalakítások vegyes alapú számrendszerek: a faktoriális féle számrendszer Fibonacci számok, a Fibonacci számrendszer
Miről lesz szó? 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
Kódolási technikák többféle kódolási technika létezik: a feldolgozandó adat, a bitsorozat egy átalakítási módját jelenti kódolási módszerek, kódok: gépi kód: bináris formában tárolja az adatokat és utasításokat Ascii kód, Unicode, UTF-8 a leíró nyelvek kódrendszere: HTML, LaTex tömörítést megvalósító kódok: Huffman kód hibajelző/hibajavító kódok: Hamming kód base64 kódolás: az SMTP (Simple Mail Transfer Protocol) átviteli protokollban használták először adatbázisok esetében ID-k tárolása weboldalak tárolás kriptográfia protokollok: kulcsok formátuma
Az ASCII kódolás 1968-ben írták le a standardot, különböző szimbólumokhoz rendel numerikus értéket 1. feladat kezdetben 128 szimbólumot kódolt, később 256 (extended ASCII) Írjunk Python függvényt, amely kíırja a képernyőre az ASCII szimbólumokat és a hozzájuk tartozó kódértékeket. def myasciitable0(): for i in range(128): print (chr(i), i) def myasciitable1(n = 0, m = 256): for i in range(n, m): print (chr(i), i) >>> myasciitable1(65, 91) >>> myasciitable1(97, 123)
Az ASCII kódolás Ha a kimenetet szeretnénk formázni: def myasciitable2(n = 0, m = 256): for i in range(n, m): print ("%4c %5i %c" % (chr(i), i, ), end = )) if i % 3 == 2: print (end = \n ) >>> myasciitable2()...
Az ASCII kódolás 2. feladat Írjunk Python függvényt, amely kíırja a képernyőre az ASCII szimbólumokat, a hozzájuk tartozó kódértékeket, és ezek bináris, oktális, illetve hexális alakját. def myasciitable3(n = 32, m = 128): for i in range(n, m): print ("%4c%5i" % (chr(i), i)), print ("%10s" % format(i, b ), end = ) print ("%4s" % format(i, o ), end = ) print ("%3s" % format(i, X ), end = ) print ("%5s" %, end = ) if i % 2 == 1: print (end = \n ) >>> myasciitable3()
Az ASCII kódolás 3. feladat Írjunk Python függvényt, amely kíırja egy állományba az ASCII szimbólumokat, a hozzájuk tartozó kódértékeket, és ezek bináris, oktális, illetve hexális alakját. def myasciitablef(n = 32, m = 128): outf = open( myascii.txt, wt ) for i in range(n, m): outf.write("%5s%5i" % (chr(i), i)) outf.write ("%11s" % format(i, b )) outf.write ("%5s" % format(i, o )) outf.write ("%4s" % format(i, X )) outf.write ("%6s" % ) if i % 3 == 1: outf.write( \n ) outf.close() >>> myasciitablef()
Bináris állományok tartalmának hexa megjelenítése 4. feladat Írjunk programot, amely megjeleníti egy állomány bájtjait hexa számrendszerben. def filehexa(): print ( kerek egy allomany nevet: ) fnev = input() try: inf = open(fnev, rb ) bytel = inf.read() inf.close() except: print ( megnyitasi/olvasasi hiba!! ) return out = open( heximage.txt, wt ) for byte in bytel: out.write(format(byte, X ) + ) out.close() >>> filehexa()
Python, unicode karakterek, az ord, chr függvények def fugv1(l): nl = [] for elem in L: nl += [ord(elem)] return nl def fugv2(l): nl = for elem in L: nl += chr(elem) return nl
Python, az index metódus Megadja azt a sorszámot (a legelsőt), amelyen egy adott karakter előfordul a karakterláncban, ha nincs benne, futási hibával leáll: >>> mstr = ( http://www.ms.sapientia.ro/ ) >>> mstr.index( / ) 5 def sorszam1(): abece = ABCDEFGHIJKLMNOPQRSTUVWXYZ print ( kerek egy nagybetut:, end = ) c = input() try: betu = abece.index(c) return betu except: print ( nem nagy betu, end = ) >>> sorszam1() kerek egy nagybetut: E 4 >>> sorszam1() kerek egy nagybetut: 3 nem nagy betu
Python, az index metódus, def sorszam2(): abece = [chr(i) for i in range(0, 65535)] print ( kerek egy karaktert:, end = ) c = input() kar = abece.index(c) return kar
Python, unicode karakterek, a random könyvtárcsomag import random, unicodedata def unicode(n, k1, k2): for i in range(0, n): temp = random.randint(k1, k2) try: c = chr(temp) print(i, c, ord(c), end = ) print(unicodedata.category(c), end = ) print(unicodedata.name(c), end = \n ) except: print ( hiba, end = \n )
Alapműveletek 2-vel, 2 k -val Szorzás 2-vel: a bináris alak, jobbról kiegészül egy 0-val: >>> 17 * 2 34 >>> bin(17) 0b10001 >>> bin(34) 0b100010 bitműveletekkel: >>> 17 << 1 34
Alapműveletek 2-vel, 2 k -val Szorzás 2 k -val: a bináris alak, jobbról kiegészül k darab 0-val: >>> 17 * 2**4 272 >>> bin(17) 0b10001 >>> bin(272) 0b100010000 bitműveletekkel: >>> 17 << 4 272
Alapműveletek 2-vel, 2 k -val Osztás 2-vel: a bináris alak bitértékei egy pozicíóval, jobbra tolódnak: >>> 59 // 2 29 >>> bin(59) 0b111011 >>> bin(29) 0b11101 bitműveletekkel: >>> 59 >> 1 29
Alapműveletek 2-vel, 2 k -val Osztás 2 k -val: a bináris alak bitértékei k pozicíóval jobbra tolódnak: >>> 59 // 2**4 3 >>> bin(59) 0b111011 >>> bin(3) 11 bitműveletekkel: >>> 59 >> 4 3
Bitműveletek >>> x = 30 >>> y = 21 >>> format(x, b ) 11110 >>> format(y, b ) 10101 >>> x & y #bitenkenti és (AND) művelet 20 >>> format(20, b ) 10100 >>> x y #bitenkenti vagy (OR) művelet 31 >>> format(31, b ) 11111
Bitműveletek >>> x = 30 >>> y = 21 >>> format(x, b ) 11110 >>> format(y, b ) 10101 >>> x ^ y #bitenkenti kizáró vagy (XOR) művelet 11 >>> format(11, b ) 1011 >>> x = 30 >>> format(~x, b ) #negacio: 2-es komplement -11111 >>> format(-x - 1, b ) -11111
Bitműveletek, maradékosztás 2-vel def bitm1(szam): if szam % 2: print ( paratlan szam ) else: print ( paros szam ) def bitm2(szam): if szam & 1: print ( paratlan szam ) else: print ( paros szam )
Bitműveletek, maradékosztás 2 k -val def bitm3(szam): temp = szam % 256 if temp >= 32: print (chr(temp)) else: print ( nem nyomtathato karakter ) def bitm4(szam): temp = szam & 255 if temp >= 32: print (chr(temp)) else: print ( nem nyomtathato karakter )
Bitműveletek 5. feladat Hány 1-es bitet tartalmaz egy természetes szám kettes számrendszerbeli alakja? Más megfogalmazásban határozzuk meg a Hamming-súlyát egy adott számnak. (Nem kell összetéveszteni a Hamming távolsággal) Számoljuk meg, hogy hányszor kerülnek végrehajtásra a while-ban levő utasítások. def HammingW1(nr): db = 0 itnr = 0 while nr: db += (nr & 1) nr >>= 1 itnr += 1 return db, itnr >>> HammingW1(1023) >>> HammingW1(1024) (10, 10) (1, 11)
Bitműveletek Hatékonyabb a következő megoldás, ha kevés az 1-es bitek száma, ugyanis csak annyi iterációra kerül sor, ahány 1-es bit van a számban: def HammingW2(nr): db = 0 itnr = 0 while nr: nr &= nr - 1 db += 1 itnr += 1 return db, itnr >>> HammingW2(1023) >>> HammingW2(1024) (10, 10) (1, 1)
Bitműveletek 6. feladat Határozzuk meg egy természetes szám paritás-értékét, azaz hogy páros számú 1-es bitet tartalmaz vagy sem. def paritas(nr): p = 1 while nr: nr &= nr - 1 p = -p return p >>> paritas(1023) #paros szamu 1-es bitet tartalmaz 1 >>> paritas(1024) #paratlan szamu 1-es bitet tartalmaz -1
Bitműveletek 7. feladat Titkosítsunk egy karakterláncot: végezzünk XOR műveletet a karakterlánc karakterjei (bájtjai) és egy kulcs-karakterlánc karakterjei között. def crypt(mystr, key): crstr = i = 0 n = len(key) for elem in mystr: crstr += crypte(elem, key[i]) if i == n-1: i = 0 i += 1 return crstr def crypte(kar, crkar): return chr(ord(kar) ^ ord(crkar)) >>> crypt( Jó reggelt elso/másod év!!, passwd )... Hogy fejtem vissza a rejtjelezett szöveget?
Python3 stringek Python3-ban minden string unicode kódként van eltárolva. A stringek átalakíthatóak bájttömbökké alkalmazva az encode, decode, bytes függvényeket. A csak ASCII kódokat tartalmazó stringek a b prefix segítségével is átalakíthatóak: >>> mstr = muszaki egyetem >>> mstr[1] u >>> estr = mstr.encode() >>> estr[1] 197 >>> mstr = b muszaki egyetem >>> mstr[1] 197 >>> mstr1 = műszaki egyetem >>> mstr1[1] ű >>> estr1 = mstr1.encode() >>> estr1[1] 197 >>> bytes(mstr) b muszaki egyetem >>> bytes(mstr1, utf-8 ) b m\nxc5 \nxb1szaki egyetem >>> bytes([197, 123, 67, 54, 221]) b \nxc5{c6 \nxdd >>> mstr1 = b műszaki egyetem SyntaxError: bytes can only contain ASCII literal characters.
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() 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