Sichere Programmierung Lerneinheit 1: Einführung in Python Prof. Dr. Christoph Karg Studiengang Informatik Hochschule Aalen Sommersemester 2017 10.3.2017 Gliederung • • • • • • • • Einleitung Variablen Kontrollstrukturen Datentypen Listen & Dictionaries Dateioperationen Skripterstellung Nutzung von Virtual Environments Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 2 / 75 Vorbereitung Vorbereitung • Für den praktischen Teil der Vorlesung wird eine Virtuelle Maschine benötigt. • Voraussetzung für den Betrieb der Virtuellen Maschine ist ein 64-Bit Betriebssystem mit installierter VirtualBox Software. • Die Virtuelle Maschine steht über Dropbox zum Download bereit. • Der Download wird gestartet, indem man auf dieses Wort klickt. • Das Passwort für den Zugang lautet rae0wahKoo]T. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 3 / 75 Einleitung Wissenswertes über Python Wissenswertes über Python • • • • • Einfach zu benutzende Programmiersprache Interpreter-basiert High-Level Datentypen Umfangreiche Modul-Bibliothek Benannt nach der BBC Serie Monty Python’s Flying Circus“ ” Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 4 / 75 Einleitung Wissenswertes über Python Wesentliche Unterschiede zu C/C++/Java/… • Interpreter-basiert ⇝ kein Kompilieren/Linken des Codes notwendig • Keine Deklaration von Datentypen ⇝ Ermittlung des Typs einer Variablen aus dem Kontext • Keine Blockklammerungen ⇝ Strukturierung des Codes durch Einrückung • Leistungsfähige Operationen für Variablen ⇝ Einfache Programmierung von komplexen Ausdrücken Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 5 / 75 Einleitung Wissenswertes über Python Verfügbare Versionen • �Python 2.x (vorzugsweise 2.6.x oder 2.7.x) ▷ Standard in vielen Linux Distributionen, Mac OSX, Windows ▷ Hohe Stabilität ▷ Keine Weiterentwicklungen mehr • �Python 3.x ▷ Zukünftiger Standard ▷ Ideal für nicht-systemkritische Anwendungen ▷ Aktive Weiterentwicklung Vorsicht: Es gibt Inkompatibilitäten zwischen Python 2 und 3 Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 6 / 75 Einleitung Entwicklungsumgebungen Entwicklungsumgebungen • �IDLE ▷ Bestandteil von Python ▷ Debugger im Lieferumfang enthalten ▷ Ideal für den Einstieg in die Python Programmierung • �PyDev ▷ Plugin für Eclipse ▷ Sehr leistungsfähig ▷ Benutzbar mit anderen Eclipse Funktionalitäten • �Pycharm ▷ Leistungsfähige IDE ▷ Durch Plugins erweiterbar Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 7 / 75 Einleitung Entwicklungsumgebungen Der erste Kontakt Der Befehl python startet den Python Interpreter in einer Konsole: �Hinweis: Der Befehl python2 (bzw. python3) startet einen Python 2.x (3.x) Interpreter Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 8 / 75 Einleitung Entwicklungsumgebungen Arbeiten mit dem Interpreter >>> print "Hallo␣Welt" Hallo Welt >>> 23*4+12 104 >>> 13/3 4 >>> 13/3.0 4.333333333333333 >>> 2**200 1606938044258990275541962092341162602522202993782 792835301376 L >>> print '%2.5f' % (10/3.0) 3.33333 Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 9 / 75 Variablen Variablen �Syntax: • Eine Variable ist eine Zeichenkette bestehend aus Buchstaben, Ziffern und Unterstrichen (_). • Das erste Symbol einer Variable muss ein Buchstabe oder ein _ sein. �Wertzuweisung: • Die Zuweisung eines Werts erfolgt mit dem Operator =. • Auf der rechten Seite des Operators = muss sich ein Term befinden. • Die Variable wird automatisch bei der ersten Zuweisung deklariert. • Der Datentyp der Variablen wird anhand des Terms festgelegt. • Der Zugriff auf eine Variable, der kein Wert zugewiesen wurde, führt zu einem Laufzeitfehler. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 10 / 75 Variablen Beispiele x = 45/2 + 5 ⇝ x ist eine ganze Zahl mit dem Wert 27 y = 45/2.0 + 5 ⇝ y ist eine Fließkommazahl mit dem Wert 27.5 s = " Hallo ␣" + "Welt" + "!" ⇝ s ist ein String mit dem Wert Hallo Welt! t = ("Data", 23) ⇝ t ist ein Paar bestehend aus einem String (Wert Data) und einer ganzen Zahl (Wert 23) Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 11 / 75 Kontrollstrukturen Kontrollstrukturen • Kontrollstrukturen: ▷ Fallunterscheidung (⇝ if) ▷ Kopfgesteuerte Schleife (⇝ while) ▷ Iterationsschleife (⇝ for) ▷ Funktionen • Es gibt keine Blockklammerungen. • Die Strukturierung des Quellkodes erfolgt mittels Einrückungen. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 12 / 75 Kontrollstrukturen Fallunterscheidung Fallunterscheidung �Aufbau: if Bedingung 1: Block 1 elif Bedingung 2: Block 2: ... elif Bedingung n: Block n else: Block n+1 �Bemerkungen: • Die elif und else Blöcke sind optional. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 13 / 75 Kontrollstrukturen Fallunterscheidung Fallunterscheidung – Beispiel n = 12 if n % 3 == 0: if n % 6 != 0: print n, "ist␣ein␣ Vielfaches ␣von␣3" else: print n, "ist␣ein␣ Vielfaches ␣von␣6" elif n % 4 == 0: print n, "ist␣ein␣ Vielfaches ␣von␣4" else: print n, "ist␣kein␣ Vielfaches ␣von␣3␣und␣4" Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 14 / 75 Kontrollstrukturen Kopfgesteuerte Schleife Kopfgesteuerte Schleife �Aufbau: while Bedingung : Block 1 else: Block 2 �Bemerkungen: • Der else-Teil ist optional und wird nach Beendigung der Schleife ausgeführt. • Ein in Block 1 ausgeführter break Befehl beendet die Schleife. In diesem Fall wird der else-Teil nicht ausgeführt. • Der Befehl continue startet den nächsten Durchlauf der Schleife. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 15 / 75 Kontrollstrukturen Kopfgesteuerte Schleife Kopfgesteuerte Schleife – Beispiel n = 15; i = 0 while i<=n: if n >20: print n, "ist␣zu␣ gross !" break print "%2d␣:␣%7d" % (i, 2**i) i = i+1 else: print n+1, " Zweierpotenzen ␣ berechnet ." Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 16 / 75 Kontrollstrukturen Kopfgesteuerte Schleife Implementierung fußgesteuerter Schleifen �Ziel: Implementierung von fußgesteuerten Schleifen unter Einsatz einer kopfgesteuerten Schleife. �Ausgangspunkt: do { Block } while Bedingung �Lösung: Einsatz eines Flags, um die Schleife mindestens einmal zu durchlaufen. first =true while first || Bedingung : first=false Block Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 17 / 75 Kontrollstrukturen Kopfgesteuerte Schleife Fußgesteuerte Schleife – Beispiel �Gegeben: n = 10; i = 0 do { print "%2d␣:␣%7d" % (i, 2**i)) } while i<=n �Python-Implementierung: n = 10; i = 0; first = True while first or i<=n: first = False print "%2d␣:␣%7d" % (i, 2**i) i = i + 1 Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 18 / 75 Kontrollstrukturen Iterationsschleife Iterationsschleife �Aufbau: for Variablen in Liste : Block 1 else: Block 2 �Bemerkungen: • Der else-Teil ist optional und wird nach Beendigung der Schleife ausgeführt. • Ein in Block 1 ausgeführter break Befehl beendet die Schleife. In diesem Fall wird der else-Teil nicht ausgeführt. • Der Befehl continue startet den nächsten Durchlauf der Schleife • Die Liste darf im Schleifenrumpf nicht verändert werden. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 19 / 75 Kontrollstrukturen Iterationsschleife Iterationsschleife – Beispiel liste = ["Dies", "ist", "ein", " langer ", "Text" ] cntr = 0 for x in liste: print x cntr = cntr + 1 else: print cntr , "Wörter␣ ausgegeben " Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 20 / 75 Datentypen Übersicht Datentypen in Python • • • • • Datentypen für Zahlen Sequenzen (Tupel) Listen Zeichenketten (aka Strings) Assoziative Arrays (aka Dictionaries) Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 21 / 75 Datentypen Datentypen für Zahlen Datentypen für Zahlen • Unterstützte Zahlentypen: ▷ Ganze Zahlen ▷ Fließkommazahlen ▷ Komplexe Zahlen • Genauigkeit ▷ Ganze Zahlen ⇝ exakt (nur durch Hauptspeicher begrenzt) ▷ Fließkommazahlen ⇝ im Kontext konfigurierbar Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 22 / 75 Datentypen Datentypen für Zahlen Auswahl von Operatoren für Zahlen Operator a + b a - b a * b a ** b a / b a % b a // b round(x) str(x) Bedeutung Addition von a und b Subtraktion von a und b Multiplikation von a und b Exponentation von a und b (d.h. ab ) Division von a und b a modulo b Division von a und b und Abrunden auf die nächstkleinste ganze Zahl Runden von x Konvertierung von x in einen String Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 23 / 75 Datentypen Datentypen für Zahlen Bemerkungen • • • • In Python gibt es keine Inkrement- oder Dekrementoperatoren. Anstatt x = x+1 kann man auch x += 1 schreiben. Für die anderen Grundrechenarten existieren analoge Operatoren. Das Modul math enthält eine Vielzahl weiterer mathematischer Operationen und Funktionen. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 24 / 75 Datentypen Sequenzen Sequenzen (Tupel) • Python bietet die Möglichkeit, Daten als Tupel zu gruppieren. • Ein Tupel wird erzeugt, indem man die Elemente klammert: t = (1 ,3 ,5) • Die Klammerung ist optional: t = 1,3,5 • Zugriff auf die Elemente eines Tupels: (a,b,c) = t Hierbei ist auf die Dimension des Tupels zu achten • Man kann Sequenzen auch verschachteln: t = (1 ,(2 ,3) ,8) Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 25 / 75 Datentypen Listen Listen • Python stellt mit Listen eine leistungsfähige Datenstruktur bereit. • Der Inhalt einer Liste ist dynamisch verwaltbar. • Die Elemente einer Liste werden mittels einer for-Schleife durchlaufen. • Es gibt eine Vielzahl von Funktionen zur Verarbeitung von Listen. • Durch Verschachtelung von Listen kann man beispielsweise Arrays erzeugen. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 26 / 75 Datentypen Listen Arbeit mit Listen • Leere Liste erzeugen: L = [] • Liste mit den Elementen 23, Hallo, Welt, 42 und 9 erzeugen: L = [ 23, " Hallo ", "Welt", 42, 9 ] • Element 12 ans das Ende der Liste anhängen: L. append (12) • Anzahl der in der Liste enthaltenen Elemente ausgeben: print len(L) Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 27 / 75 Datentypen Listen Der Range Befehl • Der Befehl �range() dient zur Erzeugung von Zahlenfolgen. • �Variante 1: range(stop) ▷ Erzeugt die Liste [0,1,2,...,stop-1] ▷ Ist stop ≤ 0, dann ist die Liste leer • �Variante 2: range(start,stop[,step]) ▷ Erzeugt die Liste [start, start + step, start + 2 · step, . . . , start + i · step] wobei i = max{start + j · step | j = 0, 1, 2, . . .} ▷ step ist optional (Defaultwert 1) ▷ step muss ungleich 0 sein Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 28 / 75 Datentypen Listen Beispiele für range() >>> range (10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> range (3 ,10) [3, 4, 5, 6, 7, 8, 9] >>> range (3 ,10 ,2) [3, 5, 7, 9] >>> range ( -4 ,10 ,2) [-4, -2, 0, 2, 4, 6, 8] >>> range ( -4,10,-2) [] >>> range (10 ,3) [] Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 29 / 75 Datentypen Listen Zugriff auf Listen �Variante 1: Einsatz einer for-Schleife L = range (1 ,20 ,2) for x in L: print x �Variante 2: Einsatz des Klammeroperators [] for i in range (0, len(L)): print L[i] �Beachte: Listenelemente sind änderbar print L[3] L[3] = 25 print L[3] Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 30 / 75 Datentypen Listen Auswahl von Teillisten Mit dem �Klammeroperator [] kann man Teile einer Liste auswählen. �Anwendung: • L[a:b] liefert eine Liste, die die Elemente in L von Position a bis b − 1 enthält. • L[a:] liefert die Elemente in L ab Position a. • L[:b] liefert die Elemente in L bis Position b − 1. • Negative Bereichsgrenzen sind erlaubt. So liefert L[4:-1] den Inhalt von L ab dem fünften bis zum vorletzten Element. • L[:] liefert eine Kopie von L. �Beachte: Fehlerhafte Bereichsangaben werden passend korrigiert. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 31 / 75 Datentypen Listen Weitere nützliche Befehle • L.append(x): das Element x wird an das Ende von L angehängt. • L.insert(i,x): Fügt das Element x an der Position i in die Liste ein. • L.extend(L2): die Liste L2 wid an das Ende von L angehängt. • L.remove(x): das erste Vorkommen von x in L wird gelöscht. Ist x nicht in L enthalten, führt dies zu einem Laufzeitfehler. • L.pop([i]): das Element an der i-ten Position wird gelöscht. Wird keine Position angegeben, dann wird das letzte Element in der Liste gelöscht. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 32 / 75 Datentypen Listen Weitere nützliche Befehle (Forts.) • x in L: gibt genau dann True zurück, wenn x in L enthalten ist • x not in L: gibt genau dann True zurück, wenn x nicht in L enthalten ist • L.index(x): Liefert den Index des ersten Vorkommens von x in L. Ist x nicht in L enthalten, führt dies zu einem Laufzeitfehler • L.count(x): Zählt die Anzahl der Vorkommen von x in L • L.sort(): Sortiert die Elemente in L • L.reverse(): Kehrt die Reihenfolge der Elemente in L um Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 33 / 75 Datentypen Zeichenketten Zeichenketten • • • • Eine Zeichenkette ist ein Spezialfall einer Liste. Zeichenketten sind nicht veränderbar. Zeichenketten können mittels + konkateniert werden. Mit dem Befehl �print gibt man eine Zeichenkette auf der Konsole aus. • Mit dem Befehl ord(c) wird der Index des Zeichens c im eingesetzten Zeichensatz ermittelt. • Der Befehl chr(i) berechnet das Zeichen mit dem Index i im aktuellen Zeichensatz. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 34 / 75 Datentypen Zeichenketten Nützliche Funktionen für Zeichenketten • s[i]: liefert das i-te Zeichen in s zurück. Ist i außerhalb des zulässigen Bereichs, führt dies zu einem Laufzeitfehler. • s.isalpha(): gibt True zurück, wenn s nur Buchstaben enthält. • s.isdigit(): gibt True zurück, wenn s nur Ziffern enthält und mindestens ein Zeichen lang ist. • s.isspace(): gibt True zurück, wenn s nur Whitespace-Zeichen enthält. • s.isupper(): gibt True zurück, falls alle in s enthaltenen Buchstaben gross geschrieben sind. • s.upper(): gibt eine Kopie von s zurück, bei der alle Buchstaben gross geschrieben sind. • s.islower(), s.lower(): analog für Kleinschreibung Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 35 / 75 Datentypen Zeichenketten Zeichenketten – Beispiel s = "Ich␣bin␣ein␣ langer ␣ String ␣mit␣ Buchstaben ␣und" s += "␣1␣oder␣2␣ Ziffern ." print s for x in s: if x. isupper (): print x + "␣ist␣ein␣ grosser ␣ Buchstabe ." elif x. islower (): print x + "␣ist␣ein␣ kleiner ␣ Buchstabe ." elif x. isdigit (): print x + "␣ist␣eine␣ Ziffer ." elif x. isspace (): print x + "␣ist␣Whitespace - Zeichen ." else: print x + "␣ist␣ein␣ Sonderzeichen ." print s. upper () Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 36 / 75 Datentypen Dictionaries Dictionaries • Ein Dictionary ist eine Datenstruktur zur Speicherung von Daten mit Zugriffsschlüsseln. • Ein Datensatz besteht aus: ▷ Schlüssel ⇝ beliebige sortierbare Daten ▷ Nutzdaten ⇝ jede Art von Daten • Mit der Zuweisung D = {} wird ein leeres Dictionary D erzeugt. • Die Zuweisung D[key] = value fügt ein Datum mit dem Schlüssel key und den Nutzdaten value in das Dictionary D ein. Ist bereits ein Datum mit dem Schlüssel key vorhanden, dass wird dieses überschrieben. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 37 / 75 Datentypen Dictionaries Dictionaries – Beispiel D1 = {} D1[" Sabine "] = " 089/232323 " D1["Oskar "] = " 0711/23343434 " D1[" Andrea "] = " 0815/12345 " D1[" Martin "] = " 07361/12345 " D1["Eva"] = " 07361/12323 " D1["Paul"] = " 0711/123988 " D1[" Andrea "] = " 0815/45678 " print D1 Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 38 / 75 Datentypen Dictionaries Erzeugen von Dictionaries Mit dem Befehl { k1 : v1, k2 : v2, ..., kn : vn} wird ein Dictionary mit n Einträgen (k1 , v1 ), . . . , (kn , vn ) erzeugt. Beispiel: D2 = { (2 ,4) (3 ,2) (4 ,3) (1 ,9) : : : : " Punkt ␣1", " Punkt ␣2", " Punkt ␣3", " Punkt ␣4" } print D2 Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 39 / 75 Datentypen Dictionaries Erzeugen von Dictionaries (Forts.) Eine Liste mit Paaren kann man mit dem Befehl �dict() in ein Dictionary konvertieren. Beispiel: L = [ ("c" ,10), ("z" ,89), ("d" ,41), ("t" ,26) ] D3 = dict(L) Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 40 / 75 Datentypen Dictionaries Zugriff auf Dictionaries • Der Befehl �D.iteritems() liefert eine Liste mit Paaren aller in dem Dictionary D enthaltenen Werte. • Mit dem Befehl �D.iterkeys() kann man die Liste aller in dem Dictionary D enthaltenen Schlüssel abfragen. • Die im Dictionary D enthaltenen Werte erhält man durch den Befehl �D.itervalues(). • Mit �D.has_key(k) kann man abfragen, ob D ein Element mit dem Schlüssel k enthält. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 41 / 75 Datentypen Dictionaries Zugriff auf Dictionaries – Beispiel L = [ ("c" ,10), ("z" ,89), ("d" ,41), ("t" ,26), ("e" ,41) ] D3 = dict(L) for (k,v) in D3. iteritems (): print "Schlüssel:␣{0}␣/␣ Datum :␣{1}". format (k,v) for (k,v) in sorted (D3. iteritems ()): print "Schlüssel:␣{0}␣/␣ Datum :␣{1}". format (k,v) for k in D3. iterkeys (): print "Schlüssel:␣", k for v in D3. itervalues (): print " Datum :␣", v Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 42 / 75 Datentypen Dictionaries Beispiel: Buchstabenstatistik �Aufgabe: Zähle die in einem String vorkommenden Zeichen und gib folgende Informationen aus: 1. Zeichen mit den jeweiligen Positionen im String 2. Tabelle mit allen Zeichen, sortiert nach deren Häufigkeit �Ansatz: Benutze Listen und Dictionaries Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 43 / 75 Datentypen Dictionaries Beispiel: Buchstabenstatistik (Cont.) text = " diesisteinextremlangertextohnesinnaber " \ + " mitviiielenbuchstabenzumzaehlen " n = len(text) BT = {} for i in range (n): x = text[i] if BT. has_key (x): BT[x]. append (i) else: BT[x] = [i] H = [] Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 44 / 75 Datentypen Dictionaries Beispiel: Buchstabenstatistik (Cont.) for (x, L) in BT. iteritems (): H. append ( (len(L)/ float (n), x) ) for (f,x) in reversed ( sorted (H)): print " Zeichen :␣%s,␣Hä ufigkeit :␣%␣1.5f," \ % (x,f), " Vorkommen :", BT[x] Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 45 / 75 Funktionen Definition Definition von Funktionen �Syntax: def name(parameter1 , parameter2 , ...): Block �Bemerkungen: • Mit dem Statement return kann man einen Wert zurückgeben. • Enthält der Funktionsrumpf kein return, dann wird er bis zum Ende ausgeführt. • Die Parameterliste darf leer sein. • Man kann die Parameter mit Default-Werten belegen. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 46 / 75 Funktionen Definition Funktionen – Beispiel 1 def gcd(a,b): if b==0: return a else: return gcd(b, a%b) def lcm(a,b): return a*b/gcd(a,b) print gcd (20 ,181) print lcm (21 ,35) Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 47 / 75 Funktionen Definition Funktionen – Beispiel 2 def test(a=1,b=2,c=3): print "a:", a print "b:", b print "c:", c print test () test (6) test(b=7) test(a=6,c=7) Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 48 / 75 Funktionen Modularisierung Modularisierung • Python bietet die Möglichkeit, Quellcode zu modularisieren. • Hierzu wird der Quellcode auf mehrere Daten, sogenannte Module, verteilt. • Um auf die Funktionen eines Moduls zuzugreifen, muss das Modul importiert werden. • Es gibt zwei Importmöglichkeiten: ▷ Einbinden des kompletten Modules ▷ Einbinden einzelner Funktionen des Modules Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 49 / 75 Funktionen Modularisierung Modularisierung – Beispiel Inhalt der Datei gcdlcm.py: def gcd(a,b): if b==0: return a else: return gcd(b, a%b) def lcm(a,b): return a*b/gcd(a,b) Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 50 / 75 Funktionen Modularisierung Modularisierung – Beispiel (Forts.) �Variante 1: Import des kompletten Modules import gcdlcm print gcdlcm .gcd (21 ,105) print gcdlcm .lcm (21 ,105) �Bemerkung: Beim Aufruf der Funktion muss der Name des Moduls voran gestellt werden. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 51 / 75 Funktionen Modularisierung Modularisierung – Beispiel (Forts.) �Variante 2: Import ausgewählter Funktionen from gcdlcm import gcd , lcm print gcd (21 ,105) print lcm (21 ,105) �Bemerkung: Mit dem Befehl from module import * werden alle Funktionen des Moduls importiert. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 52 / 75 Nützliche Module Nützliche Module Python stellt eine Vielzahl von Module für alle Aspekte der Software-Entwicklung bereit. Für dieses Projekt sind folgende Module nützlich: • Modul �os: Modul für Betriebssystemzugriffe ▷ Zugriff auf Umgebungsvariablen ▷ Arbeit mit Verzeichnissen und Dateien ▷ Abfrage von Benutzerinformationen • Modul �sys: Modul mit systemspezifischen Funktionen ▷ Übergabeparameter ▷ Beendigung des Programms Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 53 / 75 Nützliche Module Das Modul os Lesen und Schreiben von Dateien • Dateien werden mit dem Befehl open(name, mode) geöffnet. • Die Parameter von open() sind: ▷ name enthält den Namen der Datei (inklusive dem Pfad). ▷ mode gibt den Zugriffsmodus an (r = lesend, w = schreibend). • • • • • Der Rückgabewert von open() ist ein File Descriptor. Die Zugriffe auf die Datei erfolgen über den File Descriptor. Mit fd.close() wird die Datei geschlossen. Mit fd.write(s) wird der String s in die Datei geschrieben. Will man Zahlen oder Listen in eine Datei schreiben, muss man sie vorher in einen String konvertieren. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 54 / 75 Nützliche Module Das Modul os Lesen und Schreiben von Dateien (Forts.) • Mit fd.read() wird der komplette Inhalt der Datei ausgelesen und als String zurück gegeben. • Eine Zeile der Datei erhält man mit fd.readline(). Durch wiederholten Aufruf kann man die Datei zeilenweise durchlaufen. • Ist das Ende der Datei erreicht, dann liefert fd.readline() einen leeren String zurück. • Alternativ nutzt man eine for-Schleife, um die Datei zeilenweise zu durchlaufen. • Der Befehl fd.readlines() liefert eine Liste mit allen Zeilen der Datei. • Mit dem Befehl fd.seek(x) kann man innerhalb der Datei zum x-ten Byte springen. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 55 / 75 Nützliche Module Das Modul os Dateien – Beispiel import os out_file = open("/tmp/data", "w") for x in range (20): out_file .write(str(x)+"\n") out_file .close () in_file = open("/tmp/data", "r") s = in_file .read () print s Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 56 / 75 Nützliche Module Das Modul os Dateien – Beispiel (Forts.) in_file .seek (0) line = in_file . readline () while len(line )>0: print line line = in_file . readline () in_file .seek (0) for line in in_file : print s in_file .seek (0) L = in_file . readlines () print L in_file . close () Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 57 / 75 Nützliche Module Das Modul sys Das Modul sys • Das Modul sys liefert Funktionen für systemnahe Dienste. • Die Liste argv enthält den Namen des ausgeführten Skripts sowie die übergebenen Parameter. • Mit exit(i) wird die Ausführung des Skripts beendet und i als Fehlercode an den aufrufenden Prozess zurück gegeben. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 58 / 75 Erstellung von ausführbaren Skripten Wissenswertes Erstellung von ausführbaren Skripten • Da Python eine interpreterbasierte Programmiersprache ist, kann man Python Programme direkt als Shell-Skript verwenden. • Unter Linux ändert man mit chmod +x datei.py die Berechtigung des Skripts, um es direkt ausführbar zu machen. • Damit das Betriebssystem den Python Interpreter startet, muss in der ersten Zeile des Skripts ein korrekter Pfad gesetzt. • Enthält der Code UTF-8 kodierte Zeichen (z.B. Umlaute), dann muss in das Skript ein sogenannter Magic Comment eingefügt werden, damit es korrekt ausgeführt wird. • Die Kommandozeilenparameter kann man mit der über das Modul sys bereit gestellte Liste argv auslesen. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 59 / 75 Erstellung von ausführbaren Skripten Beispiel Python Skript – Beispiel #! /usr/bin/ python # -*- coding : utf -8 -*# Magic comment import sys import os def gcd(a,b): if b==0: return a else: return gcd(b, a%b) def help (): print " Usage :␣" + sys.argv [0] \ + "␣<a>␣<b>" return Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 60 / 75 Erstellung von ausführbaren Skripten Beispiel Python Skript – Beispiel (Forts.) if len(sys.argv )<3: help () sys.exit (1) a = int(sys.argv [1]) b = int(sys.argv [2]) print "a␣=", a print "b␣=", b print "gcd(a,b)␣=", gcd(a,b) Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 61 / 75 Virtual Environments Virtual Environments • Virtual Environments ermöglichen die Installation unterschiedlicher Python Konfigurationen auf einem Rechner. • Ein Einsatzgebiet von Virtual Environments ist die Arbeit an mehreren Projekten mit unterschiedlichen, sich gegenseitig ausschließenden Paketabhängigkeiten. • Die Einrichtung eines Virtual Environments erfolgt mit dem Befehl virtualenv. Dieser wird über ein entsprechendes Paket bereitgestellt. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 62 / 75 Virtual Environments Beispiel Beispiel: Zwei-Faktor-Authentisierung mit Python • Zwei-Faktor-Authentisierung ist ein Verfahren zur Anmeldung eines Benutzers mit einem Passwort und einem Einweg-Passwort. • Ein Verfahren zur Generierung von Einweg-Passwörtern ist der Time-based One-time Password Algorithmus (TOTP). • TOTP kommt unter anderem beim Google Authenticator zum Einsatz. • Für Python steht TOTP über entsprechende Pakete zur Verfügung. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 63 / 75 Virtual Environments Beispiel Vorgehen 1. 2. 3. 4. Erstellen eines Virtual Environments Einspielen der für das Projekt erforderlichen Pakete Installation des Google Authenticators Entwicklung eines passenden Python Skripts Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 64 / 75 Virtual Environments Befehle Befehle zur Verwaltung von Virtual Environments • Erstellen des Virtual Environments totp-vm: > virtualenv -p /usr/bin/ python2 .7 totp -vm • Aktivieren des Virtual Environments totp-vm: > totp - esigelec /bin/ activate • Deaktivieren eines aktiven Virtual Environments: > deactivate Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 65 / 75 Virtual Environments Paketinstallation Installation der benötigten Pakete • Für das Projekt werden folgende Pakete benötigt: ▷ pyotp ⇝ Erzeugen von Einmal-Passwörtern ▷ pypng ⇝ Arbeiten mit PNG Bildern ▷ PyQRCode ⇝ Generieren von QR Codes • Die Pakete werden mit folgenden Befehlen installiert: > pip install pyotp > pip install pypng > pip install PyQRCode Wichtig: Damit die Installation im einem Virtual Environment durchgeführt wird, muss dieses aktiv sein. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 66 / 75 Virtual Environments Zwei-Faktor-Authentisierung Einbinden der Bibliotheken Die Bibliotheken werden mittels Imports eingebunden: 1 2 3 import pyotp import time import pyqrcode Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 67 / 75 Virtual Environments Zwei-Faktor-Authentisierung Variablen für die Passwörter Das Skript verwendet folgende Variablen: • mypassword ⇝ Passwort des Benutzers • mysecret ⇝ Geheimnis zur Generierung der Einmal-Passwörter Code: 4 5 # Replace 12345 with your password mypassword = " 12345 " 6 7 8 # Replace with a random generated password mysecret ="4 IOEXYNBAATXGMBS " Bemerkung: Das Geheimnis sollte durch ein Zufallspasswort ersetzt werden. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 68 / 75 Virtual Environments Zwei-Faktor-Authentisierung Generierung eines zufälligen Geheimnisses 9 10 def random_secret (): return pyotp. random_base32 () Bemerkungen: • Zur Generierung wird eine Funktion der PyOTP Bibliothek verwendet. • Das Geheimnis wird im Base32 Format kodiert. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 69 / 75 Virtual Environments Zwei-Faktor-Authentisierung Ausgabe der Einmal-Passwörter 11 12 13 14 15 16 17 def dump_otps ( secret ): totp = pyotp.TOTP( secret ) time.sleep (2) for i in range (100): print (totp.now ()) time.sleep (1) return Bemerkungen: • Die Einmal-Passwörter werden unter Verwendung des TOTP Algorithmus berechnet. • Das aktuelle Einmal-Passwort ist abhängig von der Uhrzeit des Systems. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 70 / 75 Virtual Environments Zwei-Faktor-Authentisierung Erzeugen des QR Codes 18 19 20 21 22 23 24 25 26 27 def generate_qrcode (uri , secret ): totp = pyotp.TOTP( secret ) secret_uri = totp. provisioning_uri (uri) url = pyqrcode . create ( secret_uri ) url.png("code.png", scale =6, module_color =[0 , 0, 0, 128] , background =[0 xff , 0xff , 0xcc ]) url.show () return Bemerkungen: • Der Inhalt des QR Codes besteht aus dem Geheimnis und einem Info-Text. • Der QR Code wird in einem PNG Bild abgespeichert. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 71 / 75 Virtual Environments Zwei-Faktor-Authentisierung Durchführung der Authentisierung 28 29 30 31 32 33 34 35 36 37 def two_factor_authentication (passwd , secret ): pw = raw_input (" Enter ␣ password :␣") pin = raw_input (" Enter ␣OTP:␣") totp = pyotp.TOTP( secret ) if pw != passwd or pin != totp.now (): print " Invalid ␣ password ␣or␣pin!" return False else: print " Authentication ␣ successful !" return True Bemerkungen: • Bei der Authentisierung wird ein Einmal-Passwort unter Verwendung des Geheimnisses erzeugt. • Die Authentisierung ist erfolgreich, wenn der Benutzer das korrekte Passwort und das korrekte Einmal-Passwort eingibt. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 72 / 75 Virtual Environments Anwendung des Skripts Anwendung des Skripts 1. Das Geheimnis wird mit einem zufällig generiertem Wert belegt. 2. Das Geheimnis wird im Google Authenticator gespeichert, indem man ▷ den Wert direkt eingibt, oder ▷ über den QR Code einliest. 3. Die Zwei-Faktor-Authentisierung wird mit dem Passwort und dem mit dem vom Google Authenticator generierten Einmal-Passwort durchgeführt. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 73 / 75 Zusammenfassung Zusammenfassung • Python ist eine leistungsfähige Skript-Sprache. • Der Datentyp einer Variable wird anhand des Kontexts ermittelt. • Mit Listen und Dictionaries stellt Python leistungsfähige Datenstrukturen bereit. • Durch das breite Angebot an Modulen ist Python für viele Einsatzzwecke geeignet. • Weite Informationen findet man unter http://www.python.org. • Literaturempfehlung: [Lut13; The14; Mat15] Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 74 / 75 Literatur Literatur [Lut13] Mark Lutz. Learning Python. O’Reilly, 2013. [Mat15] Eric Matthes. Python Crash Course: A Hands-On, Project-Based Introduction to Programming. No Starch Press, 2015. [The14] Thomas Theis. Einstieg in Python: Ideal für Programmieranfänger geeignet. Rheinwerk, 2014. Prof. Dr. C. Karg (HS Aalen) Sichere Programmierung Einführung in Python 75 / 75