Verschlüsselungsprogramm - Caesar
- xpilz
- User
- Beiträge: 76
- Registriert: Sonntag 11. April 2010, 12:46
- Wohnort: Deutschland
- Kontaktdaten:
Hallo Community .
Ich habe ein Verschlüsselungsprogramm fertig geschrieben und es auch ziemlich oft getestet. Ich hoffe so weit sind keine großen Fehler im Skript enthalten. Auch habe ich das Gefühl, ich habe etwas geschafft. Ich weiß nicht.. Ich betrachte es als mein erstes, richtiges, kleines Projekt.
http://python-forum.de/pastebin.php?mode=view&s=47
Was haltet ihr davon? Hoffe auf konstruktive Kritik.
mfg xpilz
Ich habe ein Verschlüsselungsprogramm fertig geschrieben und es auch ziemlich oft getestet. Ich hoffe so weit sind keine großen Fehler im Skript enthalten. Auch habe ich das Gefühl, ich habe etwas geschafft. Ich weiß nicht.. Ich betrachte es als mein erstes, richtiges, kleines Projekt.
http://python-forum.de/pastebin.php?mode=view&s=47
Was haltet ihr davon? Hoffe auf konstruktive Kritik.
mfg xpilz
Mein Python-Blog.
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
1. Shebang-Zeile sollte besser lauten
2. Es gibt `string.ascii_*` damit kann man `letters` besser erzeugen, ja auch die gemischte Version
3. `letters` ist eine Modulweite Konstante, also solltest du sie auch so behandeln
4.
geht auch als
(die magische Zahl 52 solltest du sowieso ueberall gegen `len(letters)` tauschen)
5. `shift_width` ist ein besserer Name als `value`
6. Du solltest Docstrings nutzen
7. Schau dir mal `argparse` bzw `optparse` an
Da gibts bestimmt noch viel mehr v.a. in der "Verschlüsselung" - der Code zur Entschlüsselung ist btw identisch (sollte er ja auch sein). ist besser als copy+paste. Wenn man Docstrings benutzt ist aber vllt
besser.
Code: Alles auswählen
#!/usr/bin/env python3
2. Es gibt `string.ascii_*` damit kann man `letters` besser erzeugen, ja auch die gemischte Version
3. `letters` ist eine Modulweite Konstante, also solltest du sie auch so behandeln
4.
Code: Alles auswählen
while value > 52:
value = value - 52
Code: Alles auswählen
value = value % len(letters)
5. `shift_width` ist ein besserer Name als `value`
6. Du solltest Docstrings nutzen
7. Schau dir mal `argparse` bzw `optparse` an
Da gibts bestimmt noch viel mehr v.a. in der "Verschlüsselung" - der Code zur Entschlüsselung ist btw identisch (sollte er ja auch sein).
Code: Alles auswählen
decode = encode
Code: Alles auswählen
def decode(data, shift_width):
"Docstring"
return encode(data,shift_width)
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
- xpilz
- User
- Beiträge: 76
- Registriert: Sonntag 11. April 2010, 12:46
- Wohnort: Deutschland
- Kontaktdaten:
Hallo cofi.
Zu 1: Shebang geändert.
2: Ja? Ich habe gesucht aber nichts gefunden. Vorher hatte ich ascii_letters[:26] bzw [26:] benutzt, aber dann hätte ich mehr schreiben müssen. (Jeweils einen Zweig falls der Buchstabe lower bzw. uppercase ist).
3: Aber erst wenn 2 zutrifft, oder?
7. optparse will momentan noch nicht so wie ich. help sieht er bei add_option als builtin Funktion und Parameter ohne zb. -p vorangestellt ist für mich auch noch nicht klar. Werde mir das wohl genauer anschauen müssen.
Danke. Das sowas auch geht wusste ich nicht. Aber eine Zeile ist nicht identisch.
bei encode() wird das addiert.. Ist das falsch?
Und für alles andere Dankeschön.
mfg xpilz
Zu 1: Shebang geändert.
2: Ja? Ich habe gesucht aber nichts gefunden. Vorher hatte ich ascii_letters[:26] bzw [26:] benutzt, aber dann hätte ich mehr schreiben müssen. (Jeweils einen Zweig falls der Buchstabe lower bzw. uppercase ist).
3: Aber erst wenn 2 zutrifft, oder?
7. optparse will momentan noch nicht so wie ich. help sieht er bei add_option als builtin Funktion und Parameter ohne zb. -p vorangestellt ist für mich auch noch nicht klar. Werde mir das wohl genauer anschauen müssen.
Danke. Das sowas auch geht wusste ich nicht. Aber eine Zeile ist nicht identisch.
Code: Alles auswählen
[letters.index(dletter) - value*2]
Und für alles andere Dankeschön.
mfg xpilz
Mein Python-Blog.
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Zu 2
Zu 3: Nein, dann ist das immer noch eine Konstante, es sei denn du planst zum Ver- und Entschlüsseln unterschiedliche Alphabete zu benutzen.
Zum Ver/Entschlüsseln: Mein Fehler, aber trotzdem kann man den Code auslagern:
Code: Alles auswählen
>>> import string
>>> string.ascii_lowercase
'abcdefghijklmnopqrstuvwxyz'
>>> string.ascii_uppercase
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
Zum Ver/Entschlüsseln: Mein Fehler, aber trotzdem kann man den Code auslagern:
Code: Alles auswählen
import string
LETTERS = string.ascii_letters
def _shift(letter, offset = None):
offset = offset if offset is not None else (len(LETTERS) / 2)
try:
return LETTERS[(LETTERS.index(letter) + offset) % len(LETTERS)]
except ValueError:
return letter
def encode(data, shift_width):
shift_width = int(shift_width) % len(LETTERS)
return "".join(map(lambda x: _shift(x, shift_width), data))
def decode(data, shift_width):
shift_width = - int(shift_width) % len(LETTERS)
return "".join(map(lambda x: _shift(x, shift_width), data))
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
Die Ring-Klasse von Leonidas ist auch noch ganz praktisch: http://python-forum.de/viewtopic.php?f=9&t=13080
the more they change the more they stay the same
- xpilz
- User
- Beiträge: 76
- Registriert: Sonntag 11. April 2010, 12:46
- Wohnort: Deutschland
- Kontaktdaten:
@cofi:
Deine Version ist besser. Ich musste zwar noch ein wenig gucken, aber letzendlich hab ich verstanden, wie deine Version funktioniert.
@Dav1d:
Stimmt. Danke.
Ich hätte nicht gedacht das man die Caesar Verschlüsselung mit so wenigen Zeilen bewältigen kann..
mfg, xpilz
Deine Version ist besser. Ich musste zwar noch ein wenig gucken, aber letzendlich hab ich verstanden, wie deine Version funktioniert.
@Dav1d:
Stimmt. Danke.
Ich hätte nicht gedacht das man die Caesar Verschlüsselung mit so wenigen Zeilen bewältigen kann..
mfg, xpilz
Mein Python-Blog.
Hallo!
Ich habe heute auch so ein Caesar-Verschlüsselungsprogramm geschrieben:
http://paste.pocoo.org/show/286901/
Das habe ich deswegen geschrieben, weil ich üben wollte, _nicht_, weil ich das Programm brauche.
Ist der Code übersichtlich und verständlich?
Grüße
Ich habe heute auch so ein Caesar-Verschlüsselungsprogramm geschrieben:
http://paste.pocoo.org/show/286901/
Das habe ich deswegen geschrieben, weil ich üben wollte, _nicht_, weil ich das Programm brauche.
Ist der Code übersichtlich und verständlich?
Grüße
Code: Alles auswählen
alphabet = [] # we'll save the alphabet in here
for char in ascii_lowercase:
# with this we write the characters of the alphabet into the list
alphabet.append(char)
Code: Alles auswählen
alphabet = ascii_lowercase
Code: Alles auswählen
ascii_lowercase.find(shift)
Der Rest des Codes, kann jemand anderes kommentieren
Nein, es ist das selbe wieDaMutz hat geschrieben:ist das selbe wie:Code: Alles auswählen
alphabet = [] # we'll save the alphabet in here for char in ascii_lowercase: # with this we write the characters of the alphabet into the list alphabet.append(char)
Code: Alles auswählen
alphabet = ascii_lowercase
Code: Alles auswählen
alphabet = list(ascii_lowercase)
Nicht ganz, dann ist ``alphabet`` ein String, und dann kann ich auch gleich string.ascii_lowercase benutzen (EDIT: derdon war schneller )DaMutz hat geschrieben:ist das selbe wie:Code: Alles auswählen
alphabet = [] # we'll save the alphabet in here for char in ascii_lowercase: # with this we write the characters of the alphabet into the list alphabet.append(char)
Code: Alles auswählen
alphabet = ascii_lowercase
``enumerate()`` kenne ich nicht, und wo ich nachgeschaut habe, hat sich der Sinn auch nicht erschlossenbei der nächsten Funktion 'def convert_shift(shift):'; kennst du die Funktion 'enumerate'? Die würde die Funktion vereinfachen oder noch einfacher so:ausserdem verwirrt es mich ein bisschen, wenn du 'shift' für 2 verschiedene Dinge verwendest.Code: Alles auswählen
ascii_lowercase.find(shift)
@nomnom: Der Sinn von `enumerate()` ist, dass man nicht "von Hand" einen Zähler initialisieren und hochzählen muss:
Code: Alles auswählen
In [329]: it = enumerate('hallo')
In [330]: it.next()
Out[330]: (0, 'h')
In [331]: it.next()
Out[331]: (1, 'a')
In [332]: it.next()
Out[332]: (2, 'l')
In [333]: it.next()
Out[333]: (3, 'l')
In [334]: for i, c in enumerate('hallo'):
.....: print i, c
.....:
0 h
1 a
2 l
3 l
4 o
Ah, vielen Dank!BlackJack hat geschrieben:@nomnom: Der Sinn von `enumerate()` ist, dass man nicht "von Hand" einen Zähler initialisieren und hochzählen muss:
Code: Alles auswählen
In [329]: it = enumerate('hallo') In [330]: it.next() Out[330]: (0, 'h') In [331]: it.next() Out[331]: (1, 'a') In [332]: it.next() Out[332]: (2, 'l') In [333]: it.next() Out[333]: (3, 'l') In [334]: for i, c in enumerate('hallo'): .....: print i, c .....: 0 h 1 a 2 l 3 l 4 o
muss lautenDaMutz hat geschrieben: bei der nächsten Funktion 'def convert_shift(shift):'; kennst du die Funktion 'enumerate'? Die würde die Funktion vereinfachen oder noch einfacher so:ausserdem verwirrt es mich ein bisschen, wenn du 'shift' für 2 verschiedene Dinge verwendest.Code: Alles auswählen
ascii_lowercase.find(shift)
Code: Alles auswählen
string.ascii_lowercase.find(shift + 1)
ihr habt ja recht, aber es ging mir vor allem um die Idee .
So jetzt weiter:
diese if Abfrage ist nicht nötig. Ich denke auch nicht, dass dies ein Geschwindigkeitsvorteil bringt...
was ist mit dem Bindestrich '-'? Mach es doch anders herum, prüfe ob es ein Element aus 'alphabet' ist?
So jetzt weiter:
Code: Alles auswählen
if charnumber > 25:
charnumber %= 26
Code: Alles auswählen
if char in str(range(0,9)) or char in [' ', '\n', '.', ',', ';']:
War mir nicht aufgefallen, danke!DaMutz hat geschrieben:ihr habt ja recht, aber es ging mir vor allem um die Idee .
So jetzt weiter:diese if Abfrage ist nicht nötig. Ich denke auch nicht, dass dies ein Geschwindigkeitsvorteil bringt...Code: Alles auswählen
if charnumber > 25: charnumber %= 26
Oh Mann, was bin ich denn für einer … daran habe ich gar nicht gedacht! Danke!was ist mit dem Bindestrich '-'? Mach es doch anders herum, prüfe ob es ein Element aus 'alphabet' ist?Code: Alles auswählen
if char in str(range(0,9)) or char in [' ', '\n', '.', ',', ';']:
Du hast auch nicht an die neun gedacht
Außerdem solltest du dir die folgenden Unterschiede klar machen:
Außerdem solltest du dir die folgenden Unterschiede klar machen:
Code: Alles auswählen
>>> str(range(10))
'[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]'
>>> map(str, range(10))
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
>>> string.digits
'0123456789'
Das Leben ist wie ein Tennisball.
Hm, ich hab ``str(range(9))`` einfach ausprobiert, und es hat geklappt, also hab ich mir da keine weiteren Gedanken gemacht. Vielen vielen Dank Es ist dann wohl logischer string.digits oder die Methode mit ``map()`` zu verwenden.EyDu hat geschrieben:Du hast auch nicht an die neun gedacht
Außerdem solltest du dir die folgenden Unterschiede klar machen:Code: Alles auswählen
>>> str(range(10)) '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]' >>> map(str, range(10)) ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] >>> string.digits '0123456789'
EDIT #1: Doofe Formulierung entfernt
Da mein Caesar-Programm noch echt lückenhaft war, mal ein Update
http://paste.pocoo.org/show/288933/
Jetzt funktioniert sogar die Entschlüsselung Die hat vorher nicht funktioniert, unbemerkt.
Edit: Ab jetzt muss eine Zahl eingegeben werden …
http://paste.pocoo.org/show/288933/
Jetzt funktioniert sogar die Entschlüsselung Die hat vorher nicht funktioniert, unbemerkt.
Edit: Ab jetzt muss eine Zahl eingegeben werden …
Siehst schon deutlich besser aus, 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. Möchtest du deine Codierung beibehalten, dann solltest du doppelten Code in Funktionen auslagen. Und die ganzen "j" wirst du durch die enumerate-Funktion los. Und natürlich möchtest du nicht 26 als magische Zahl benutzen, sonder die Länge der Strings.
Außerdem hätte ich noch etwas zum Nachdenken:
Im string-Modul gibt es übrigens auch eine translate-Funktion.
Sebastian
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'}
>>>
Sebastian
Das Leben ist wie ein Tennisball.
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'