def stringToByteList(s): """ wandelt ein Zeichenkette in eine Byteliste um; die Codierung erfolgt mit UTF-8 >>> stringToByteList('Schlüsselpaar') [83, 99, 104, 108, 195, 188, 115, 115, 101, 108, 112, 97, 97, 114] """ return list(bytes(s, 'utf8')) def byteListToString(byteListe): """ wandelt ein Byteliste in eine Zeichenkette um; die Codierung erfolgt mit UTF-8 >>> byteListToString([83, 99, 104, 108, 195, 188, 115, 115, 101, 108, 112, 97, 97, 114]) 'Schlüsselpaar' """ return str(bytes(byteListe), 'utf8') def blocklaenge(n): """ bestimmt die maximale Blocklänge bei vorgebenem n >>> blocklaenge(3001122295343) 5 """ if n < 256: return 0 else: if n == 256: return 1 else: return blocklaenge(n//256)+1 def byteListToNat(byteListe): """ erzeugt aus einer Liste von Bytes eine natürliche Zahl >>> byteListToNat([83, 99, 104, 108, 195]) 358150073539 """ if len(byteListe) == 1: return byteListe[0] else: return byteListe[-1] + 256*byteListToNat(byteListe[:-1]) def byteListToNatList(byteListe, blocklaenge): """ wandelt ein Liste von Bytes in eine Liste mit Zahlen um; berücksicht dabei eine vorgegebene Blocklänge >>> byteListToNatList([83, 99, 104, 108, 195, 188, 115, 115, 101, 108, 112, 97, 97, 114], 5) [358150073539, 809390794092, 1885430130] """ if len(byteListe) <= blocklaenge: return [byteListToNat(byteListe)] else: return [byteListToNat(byteListe[0:blocklaenge])] + byteListToNatList(byteListe[blocklaenge:], blocklaenge) def natToByteList(zahl): """ wandelt eine natürliche Zahl in eine Liste mit Bytes um; >>> natToByteList(358150073539) [83, 99, 104, 108, 195] """ if zahl < 256: return [zahl] else: return natToByteList(zahl//256) + [zahl%256] def natListToByteList(natListe): """ wandelt eine Liste mit natürlichen Zahl in eine Liste mit Bytes um; >>> natListToByteList([358150073539, 809390794092, 1885430130]) [83, 99, 104, 108, 195, 188, 115, 115, 101, 108, 112, 97, 97, 114] """ if natListe == []: return [] else: return natToByteList(natListe[0]) + natListToByteList(natListe[1:]) def modpot(x, y, m): """ berechnet (schnell) die modulare Potenz >>> modpot(52, 37, 77) 24 """ if y == 0: return 1 else: if y%2 == 1: return (x*modpot((x*x)%m, y//2, m))%m else: return (modpot((x*x)%m, y//2, m))%m def verschluesselnRSA(zahl, schluessel): """ verschluesselt durch modulare Potenzbildung >>> verschluesselnRSA(358150073539, (65537, 3001122295343)) 2465016304633 >>> verschluesselnRSA(2465016304633, (2384015708753, 3001122295343)) 358150073539 """ return modpot(zahl, schluessel[0], schluessel[1]) def myMap(liste, f): if liste == []: return liste else: return [f(liste[0])] + myMap(liste[1:], f) def verschluesselnListeRSA(zahlenListe, schluessel): """ verschluesselt eine Zahlenliste durch modulare Potenzbildung >>> verschluesselnListeRSA([358150073539, 809390794092, 1885430130], (65537, 3001122295343)) [2465016304633, 2630297697622, 381401817373] >>> verschluesselnListeRSA([2465016304633, 2630297697622, 381401817373], (2384015708753, 3001122295343)) [358150073539, 809390794092, 1885430130] """ h = lambda zahl: verschluesselnRSA(zahl, schluessel) return myMap(zahlenListe, h) def codierenZeichenketteZahlenliste(zeichenkette, schluessel): """ erzeugt aus einer Zeichenkette eine Folge natürlicher Zahlen >>> codierenZeichenketteZahlenliste('öffentlicher Schlüssel', 5) [840578786917, 474399664483, 448378576979, 426953720764, 1936942444] """ n = schluessel[1] b = blocklaenge(n) byteListe = stringToByteList(zeichenkette) #print('Byteliste:', byteListe) natListe = byteListToNatList(byteListe, b) return natListe def decodierenZahlenlisteZeichenkette(zahlenListe): """ erzeugt aus einer Zeichenkette eine Folge natürlicher Zahlen >>> decodierenZahlenlisteZeichenkette([840578786917, 474399664483, 448378576979, 426953720764, 1936942444]) 'öffentlicher Schlüssel' """ #print('Byteliste:', byteListe) byteListe = natListToByteList(zahlenListe) #print('Byteliste:', byteListe) zeichenkette = byteListToString(byteListe) return zeichenkette def verschluesseln(zeichenkette, schluessel, codierFunktion): """ erzeugt aus einer zu einer Zeichenkette eine Bytefolge >>> verschluesseln('öffentlicher Schlüssel', (65537, 3001122295343), codierenZeichenketteZahlenliste) [840578786917, 474399664483, 448378576979, 426953720764, 1936942444] """ #print('Zeichenkette:', zeichenkette) natListe = codierFunktion(zeichenkette, schluessel) #print('Zahlenliste:', natListe) natListeVerschluesselt = verschluesselnListeRSA(natListe, schluessel) #print('Zahlenliste:', natListeVerschluesselt) return natListeVerschluesselt def entschluesseln(natListe, schluessel, decodierFunktion): """ erzeugt aus einer Bytefolge eine Byteliste >>> entschluesseln([840578786917, 474399664483, 448378576979, 426953720764, 1936942444], (2384015708753, 3001122295343), decodierenZahlenlisteZeichenkette) 'öffentlicher Schlüssel' """ #print('Zahlenliste:', natListe) natListeEntschluesselt = verschluesselnListeRSA(natListe, schluessel) #print('Zahlenliste:', natListeEntschluesselt) zeichenkette = decodierFunktion(natListeEntschluesselt) #print('Zeichenkette:', zeichenkette) return zeichenkette