Caesar Cipher

# PSEUDOCODE fuer Caeser Encryption/Decryption
# Die Caeser-Verschluesselungsmethode:
# Alle Buchstaben werden im Alphabet um eine bestimmte Anzahl
# an Buchstaben weitergerückt -> Ciphertext

# DIESER CODE FUNKTIONIERT NUR MIT GROSSBUCHSTABEN ALS INPUT
# AUCH UMLAUTE UND SATZZEICHEN GEHEN NICHT
# ============================================

# fn encrypt(plaintext, key):

#   ciphertext := ""

#   alphabet := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

#   fuer buchstabe in plaintext:

#     index := alphabet.index(buchstabe)

#     neuer_buchstabe := alphabet[(index + key) mod 26]

#     ciphertext += neuer_buchstabe

#   return ciphertext

# fn decrypt(ciphertext, key):

#   return encrypt(ciphertext, 26-key)

# Aufgabe 1: Schreibe aus dem obigen Pseudocode die encrypt und decrypt Methoden
# Aufgabe 2: Schreibe Code, um die obigen Funktionen zu testen (interaktiv mit input???)
# Aufgabe 3: Schreibe eine Funktion, die die Caeser-Verschlüsselung bricht, indem sie
#            alle key-Werte in Folge ausprobiert und das Dechiffrat ausgibt! (Bruteforce)

Vigènere Cipher

# PSEUDOCODE fuer Vigenere Encryption/Decryption
# Die Vigenere-Verschluesselungsmethode:

# Jeder einzelne Buchstabe wird um eine bestimmte Anzahl an
# Buchstaben im Alphabet verrückt, die durch einen zweiten String
# festgelegt werden, dem Key. Die "Verrückungsanzahl" wird durch die
# Position des Buchstaben des Keys im Alphabet festgelegt. Beispiel:

#      Plaintext:           GEHEIMENACHRICHT
#      Key:                 GEHEIMSCHLUESSEL

#   Plaintext Positionen:   6  4 7  4 8  12 4  13 0 2  7  17 8  2  7  19
#       Key Positionen:     6  4 7  4 8  12 18 2  7 11 20 4  18 18 4  11

#   Addierte Positionen:    12 8 14 8 16 24 22 15 7 13 27 21 26 20 11 30
#        mod 26:            12 8 14 8 16 24 22 15 7 13 1  21 0  20 11 4

#      Ciphertext:          M  I O  I Q  Y  W  P  H N  B  V  A  U  L  E

# Falls der Schluessel kuerzer als der zu verschluesselnde Text ist,
# wird der Schluessel lediglich wiederholt

# DIESER CODE FUNKTIONIERT NUR MIT GROSSBUCHSTABEN ALS INPUT
# AUCH UMLAUTE UND SATZZEICHEN GEHEN NICHT
# ============================================

# alphabet := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

# fn encrypt(plaintext, key):

#   ciphertext := ""

#   fuer i in range(len(plaintext)):

#     b  = plaintext[i]
#     bi = alphabet.index(b)    // Position im Alphabet herausfinden

#     k = key[i % len(key)]     // Wichtig: mod len(key) weil wir den schluessel ja wiederholen wollen, falls nicht langgenug
#     ki = alphabet.index(k)

#     ciphertext += alphabet[(bi + ki) % 26]     // Buchstabe herausfinden, der mit den addierten Positionen korrespondiert

#   return ciphertext

# Aufgabe 1: Schreibe aus dem obigen Pseudocode die encrypt-Funktion
# Aufgabe 2: Schreibe eine decrypt-Funktion. TIPP: key muss wieder abgezogen werden
# Aufgabe 3: Teste deine Methoden (maybe interaktiv mit input??)

RSA

from math import gcd  # ggt (greatest common divisor)

# Definition einer Funktion zur Durchführung des RSA-Verfahrens
def calc_rsa_keys(p: int, q: int) :

print('Primzahl p =',p)
print('Primzahl q =',q)

# Berechnung von N
N = p * q
print('N =',N)

# Berechnung der Eulerschen phi-Funktion von N
phiN = (p - 1) * (q - 1)
print('phiN =',phiN)

# Auswahl des oeffentlichen Schluessels, e
#for e in range(2, phiN):
for e in range(20, phiN):
if gcd(e,phiN)==1 :
break
print('oeffentlicher Schluessel e =',e)

# privater Schluessel: Berechnung der Inversen zu e mod phiN
d = 0
while True:
if (d * e) % phiN == 1:
break
d += 1
print('privater Schluessel d =',d)
return [ N, e, d ]

# Verschluesselung durchfuehren
def code(m, e, N) :
return (m**e) % N

# Entschluesselung durchfuehren
def decode(c, d, N) :
return (c**d) % N

'''

print('######## TEST 0: ########')

p = 3
q = 11

[ N, e, d ] = calc_rsa_keys(p, q)

x = 4
c =   code( x, e, N)
m = decode( c, d, N)

print('Nachricht:',x)
print('Chiffrat:',c)
print('Klartext:',m)

'''

print('######## TEST 1: ########')
# [<https://de.wikipedia.org/wiki/RSA-Kryptosystem>](<https://de.wikipedia.org/wiki/RSA-Kryptosystem>)
p = 11
q = 13

[ N, e, d ] = calc_rsa_keys(p, q)

m = 7
c  =   code(m, e, N)
dc = decode(c, d, N)

print('Nachricht m =',m)

print('Chiffrat (m ** e) % N =', c )

print('Klartext (c ** d) % N =', dc )

print('######## TEST 2: ########')

p = 11
q = 13

[ N, e, d ] = calc_rsa_keys(p, q)

Nachricht = 'Hallo hier bin ich!'
print('Nachricht:',Nachricht)

cc = ''
for m in Nachricht :
c = code(ord(m), e, N)
print(m,ord(m),c)
cc = cc+chr(c)

#cc=''
print('Chiffrat:',cc)

mm = ''
for c in cc :
m = chr( decode(ord(c), d, N) )
mm = mm+m
print('Klartext:',mm)