Seite 2 von 2
Re: Verschlüsselungsprogramm - Caesar
Verfasst: Mittwoch 10. November 2010, 19:34
von nomnom
Hallo EyDu

Ersteinmal: Vielen vielen Dank!
EyDu hat geschrieben:[…], aber warum machst du eine Unterscheidung zwischen Groß- und Kleinbuchstaben. Das kann man alles in einem Rutsch erledigen, auch wenn das Ergebnis dann eventuell ein wenig anders ist. […]
Okay, ich werde dann mal überlegen.
Möchtest du deine Codierung beibehalten, dann solltest du doppelten Code in Funktionen auslagen.
Was hat das mit Codierung zu tun?
Und die ganzen "j" wirst du durch die enumerate-Funktion los.
`enumerate` habe ich kurz nachdem ich das Programm am Anfang geschrieben habe kennengelernt, und habe danach nicht daran gedacht, da es ja so schon gut ist.
Und natürlich möchtest du nicht 26 als magische Zahl benutzen, sonder die Länge der Strings.
Wieso? Ist das etwa bei anderen möglicherweise anders? In der Doku steht:
The lowercase letters 'abcdefghijklmnopqrstuvwxyz'. This value is not locale-dependent and will not change.
Außerdem hätte ich noch etwas zum Nachdenken:
Code: Alles auswählen
>>> alpha = string.ascii_lowercase
>>> offset = 3
>>> dict(zip(alpha, alpha[offset:]+alpha[:offset]))
{'a': 'd', 'c': 'f', 'b': 'e', 'e': 'h', 'd': 'g', 'g': 'j', 'f': 'i', 'i': 'l', 'h': 'k', 'k': 'n', 'j': 'm', 'm': 'p', 'l': 'o', 'o': 'r', 'n': 'q', 'q': 't', 'p': 's', 's': 'v', 'r': 'u', 'u': 'x', 't': 'w', 'w': 'z', 'v': 'y', 'y': 'b', 'x': 'a', 'z': 'c'}
>>>
Habe ich auch heute erst kennen gelernt, beim Lesen des Tutorials. Interessant, danke.
Im string-Modul gibt es übrigens auch eine translate-Funktion.
Danke, aber ich krieg es nicht hin, damit umzugehen
Sebastian
Jakob
Re: Verschlüsselungsprogramm - Caesar
Verfasst: Mittwoch 10. November 2010, 19:36
von nomnom
derdon hat geschrieben:Am einfachsten bleibt aber immer noch str.encode
Code: Alles auswählen
>>> import string
>>> string.printable
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
>>> string.printable.encode('rot13')
'0123456789nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
Super, nur irgendwie ein bisschen unnütze, wenn man nicht nur Rot13 machen will

Re: Verschlüsselungsprogramm - Caesar
Verfasst: Mittwoch 10. November 2010, 19:51
von nomnom
So, jetzt habe ich es nach EyDus Tipps umgeschrieben:
http://paste.pocoo.org/show/289109/
Nur das mit ``zip()`` und ``string.translate()`` habe ich noch nicht gemacht.
Re: Verschlüsselungsprogramm - Caesar
Verfasst: Mittwoch 10. November 2010, 20:21
von derdon
nomnom: War ja auch nicht ernst gemeint

Re: Verschlüsselungsprogramm - Caesar
Verfasst: Donnerstag 11. November 2010, 00:10
von /me
derdon hat geschrieben:Code: Alles auswählen
>>> import string
>>> string.printable
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
>>> string.printable.encode('rot13')
'0123456789nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
ROT-13 ist mir eigentlich zu unsicher. Ich hatte eher an die doppelte Verschlüsselungsstärke gedacht. Hat schon mal jemand ROT-26 implementiert?
Re: Verschlüsselungsprogramm - Caesar
Verfasst: Donnerstag 11. November 2010, 00:26
von cofi
/me hat geschrieben:Hat schon mal jemand ROT-26 implementiert?
Viel zu unsicher! Ich nehm 2 Mal ROT13.
Re: Verschlüsselungsprogramm - Caesar
Verfasst: Donnerstag 11. November 2010, 10:26
von EyDu
Wenn ich deinen Code anpassen müsste, würde ich so vorgehen:
Code: Alles auswählen
def encrypt_caesar(shift, plain, alpha=string.ascii_letters):
cipher = []
for char in plain:
for i, element in enumerate(alpha):
if char == element:
charnumber = (i + shift) % len(alpha)
chipher.append(string.ascii_letters[charnumber]
break
else:
cipher.append(char)
return "".join(cipher)
Dabei ändert sich dann natürlich die Codierung, da, bei einer Verschiebung von 1, das "z" nicht mehr auf das "a" fällt, sondern auf das "A".
Das du "len" statt einer magischen Zahlen benutzen solltest hat ganz einfache Gründe: Die 26 sagt erstmal gar nichts aus und bei etwas komplexeren Programmen wirst du in zwei Wochen nicht mehr wissen, für was die Zahl steht. Und nun stelle dir vor, das du dein Programm erweiter möchtest: vielleicht etwas ganz abgefahrenes, wie das Hinzunehmen von Ziffern

An wie vielen Stellen müsstest du dein Programm ändern, wenn du so etwas durchführen willst? Im Idealfall bei einer: du passt nur das Alphabet an, der Rest geht automatisch. Bei deiner alten Lösung müsstest du an mehreren Stellen basteln und darfst keine vergessen.
Der nächste Schritt bei dir ist, von der for-Schleife weg zu kommen und ein Dictionary einzusetzen (oder zunächst einmal die find-Methode auf Strings). Dann solltest du dir noch die get-Methode auf Dictionaries anschauen, mit etwas Überlegung kannst du dir auch den Sonderfall für nicht zu kodierende Zeichen einsparen.
Und zum translate:
Code: Alles auswählen
>>> translation = string.maketrans("abcdefghij", "0123456789")
>>> string.translate("Spam and Eggs", translation)
'Sp0m 0n3 E66s'
Re: Verschlüsselungsprogramm - Caesar
Verfasst: Donnerstag 11. November 2010, 16:20
von nomnom
/me hat geschrieben:derdon hat geschrieben:Code: Alles auswählen
>>> import string
>>> string.printable
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
>>> string.printable.encode('rot13')
'0123456789nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
ROT-13 ist mir eigentlich zu unsicher. Ich hatte eher an die doppelte Verschlüsselungsstärke gedacht. Hat schon mal jemand ROT-26 implementiert?
Hm, ich denke da an sowas:
Code: Alles auswählen
def encrypt(plain_text):
cipher = plain_text
return cipher
def decrypt(cipher):
plain_text = cipher
return plain_text
text = raw_input('Type in your text! ')
while text != '':
text += raw_input('> ')
print "Encrypted:", encrypt(text)
print "Decrypted:", decrypt(text)
Re: Verschlüsselungsprogramm - Caesar
Verfasst: Freitag 12. November 2010, 14:55
von nomnom
EyDu hat geschrieben:
Dabei ändert sich dann natürlich die Codierung, da, bei einer Verschiebung von 1, das "z" nicht mehr auf das "a" fällt, sondern auf das "A".
Das möchte ich aber auf keinen Fall :/
Das du "len" statt einer magischen Zahlen benutzen solltest hat ganz einfache Gründe: Die 26 sagt erstmal gar nichts aus und bei etwas komplexeren Programmen wirst du in zwei Wochen nicht mehr wissen, für was die Zahl steht […]
Oh, ja, stimmt!
Der nächste Schritt bei dir ist, von der for-Schleife weg zu kommen und ein Dictionary einzusetzen (oder zunächst einmal die find-Methode auf Strings).
Ich habe mal das Programm umgeschrieben, dass es ``str.find()`` benutzt:
http://paste.pocoo.org/show/290419/
Dann solltest du dir noch die get-Methode auf Dictionaries anschauen, mit etwas Überlegung kannst du dir auch den Sonderfall für nicht zu kodierende Zeichen einsparen.
Und zum translate:
Code: Alles auswählen
>>> translation = string.maketrans("abcdefghij", "0123456789")
>>> string.translate("Spam and Eggs", translation)
'Sp0m 0n3 E66s'
Das kommt später dann, muss jetzt los

Re: Verschlüsselungsprogramm - Caesar
Verfasst: Freitag 12. November 2010, 15:40
von EyDu
Das charnumber=0 kannst du einsparen.
Re: Verschlüsselungsprogramm - Caesar
Verfasst: Freitag 12. November 2010, 18:46
von nomnom
So, mit Dictionary:
http://paste.pocoo.org/show/290515/
Aber ich fühle mich immer schlecht, wenn ich Code von anderen fast 1:1 übernehme (auch wenn ich es verstanden hab).

Re: Verschlüsselungsprogramm - Caesar
Verfasst: Freitag 12. November 2010, 18:58
von EyDu
Hat es einen Grund, dass du zwei Dictionaries verwendest?

Re: Verschlüsselungsprogramm - Caesar
Verfasst: Freitag 12. November 2010, 19:31
von nomnom
EyDu hat geschrieben:Hat es einen Grund, dass du zwei Dictionaries verwendest?

Ich denke ja. Ich möchte, dass Groß- und Kleinschreibung richtig bleiben!11!1!einself!1!1

Re: Verschlüsselungsprogramm - Caesar
Verfasst: Freitag 12. November 2010, 19:51
von EyDu
Code: Alles auswählen
translation = dict(zip(l+u, l[shift:]+l[:shift]+u[shift:]+u[:shift]))
Re: Verschlüsselungsprogramm - Caesar
Verfasst: Freitag 12. November 2010, 20:07
von nomnom
EyDu hat geschrieben:Code: Alles auswählen
translation = dict(zip(l+u, l[shift:]+l[:shift]+u[shift:]+u[:shift]))
Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah!
http://paste.pocoo.org/show/290544/ <-- Neuer Code
Re: Verschlüsselungsprogramm - Caesar
Verfasst: Freitag 12. November 2010, 20:38
von jerch
Da Du Dich mit Verschiebechiffren beschäftigst, hier mal als Anregung mit veränderlichem Offset und Schlüssel (Rotorstellungen):
Code: Alles auswählen
from string import printable
from collections import deque
CHARS = printable
class Rotor(deque):
def __init__(self, chars, period, start, direction):
self.start = chars[start]
self.period = period
self.actual_step = 0
self.direction = direction
deque.__init__(self, chars)
while self[0] != self.start:
self.rotate(1)
def get_char(self, num):
self.actual_step += 1
if self.period <= self.actual_step:
self.actual_step = 0
self.rotate(self.direction)
return self[num]
class NotEnigma(object):
def __init__(self, it, chars=CHARS):
self.chars = chars
self._rotors = [Rotor(chars, period, start, direction)
for period, start, direction in it]
def translate(self, s):
for rotor in self._rotors:
s = ''.join(rotor.get_char(self.chars.index(i)) for i in s)
return s
s = 'Hello World!'
ne1 = NotEnigma(((1, 5, -7), (2, 13, -17)))
encrypted = ne1.translate(s)
print encrypted # --> '":1b5/%/ ~%
ne2 = NotEnigma(((1, -5, 7), (2, -13, 17)))
print ne2.translate(encrypted) # --> Hello World!
Damit gewinnst Du Sicherheit, da Häufigkeitsgipfel geglättet werden. Das Prinzip ist an die Enigma angelehnt. Diese hatte allerdings noch ein paar mehr technische Einzelheiten, die z.T. der Sicherheit zuträglich als auch abträglich waren (unterschiedliche Zeichenverdrahtungen pro Scheibe, Umkehrscheibe, Steckerbrett).
Re: Verschlüsselungsprogramm - Caesar
Verfasst: Samstag 13. November 2010, 17:31
von EyDu
Und jetzt erinnerst du dich noch einmal an "dict.get"
Code: Alles auswählen
l = string.ascii_lowercase
u = string.ascii_uppercase
cipher = []
translation = dict(zip(l+u, l[shift:]+l[:shift]+u[shift:]+u[:shift]))
for char in plain:
cipher.append(translation.get(char, char)
return "".join(cipher)[/code]
Wo bei du die Schleife gleich als List Comprehension schreiben könntest:
Code: Alles auswählen
cipher = [translation.get(char, char) for char in plain]
Oder mit map:
Oder gleich zum return:
Code: Alles auswählen
return "".join(translation.get(char, char) for char in plain)
Re: Verschlüsselungsprogramm - Caesar
Verfasst: Samstag 13. November 2010, 22:21
von nomnom
EyDu hat geschrieben:Und jetzt erinnerst du dich noch einmal an "dict.get" ;-)
Code: Alles auswählen
l = string.ascii_lowercase
u = string.ascii_uppercase
cipher = []
translation = dict(zip(l+u, l[shift:]+l[:shift]+u[shift:]+u[:shift]))
for char in plain:
cipher.append(translation.get(char, char)
return "".join(cipher)[/code]
Dieses
default hab ich beim Lesen der Doku nicht verstanden :-/
Wo bei du die Schleife gleich als List Comprehension schreiben könntest:
Code: Alles auswählen
cipher = [translation.get(char, char) for char in plain]
Oder mit map:
Oder gleich zum return:
Code: Alles auswählen
return "".join(translation.get(char, char) for char in plain)
Wow, dann wird der Code ja gleich total überschaubar … vielen vielen vielen vielen Dank, EyDu :-)
Edit #1:
Das ist übrigens die
finale Version gewesen :D