Verschlüsselung in Python

Fragen zu Tkinter.
Antworten
Malte Dev
User
Beiträge: 4
Registriert: Sonntag 14. April 2019, 11:18

Hallo! Ich bin ein Python-Anfänger und habe versucht, eine Verschlüsselung in tkinter zu programmieren. Ab diesem Punkt komme ich nicht mehr weiter. Hier der Code: (Bitte den überarbeiteten Code schicken :D)

import tkinter

def getit(event):
satz = e1.get()
key = "geheim"
verschluesselt = verschluessele(satz,key)
entschluesselt = entschluessele(verschluesselt,key)
b1.bind("<Button-1>",verschluessele(satz,key))

def verschluessele(s,k):
ret = ""
for zeichen in range(len(s)):
ret = ret + chr(ord(s[zeichen]) + ord(k[zeichen%len(k)])-ord(k[(zeichen+1)%len(k)])+50)
return ret

def entschluessele(s,k):
ret = ""
for zeichen in range(len(s)):
ret = ret + chr(ord(s[zeichen]) - ord(k[zeichen%len(k)])+ord(k[(zeichen+1)%len(k)])-50)
return ret

w1 = tkinter.Tk()
w1.title("Verschlüsseler von Malte Dev")

e1 = tkinter.Entry(w1)
e1.pack()

l1 = tkinter.Label(w1,text="")
l1.pack()

b1 = tkinter.Button(w1,text="Verschlüsseln")
b1.pack()
b1.bind("<Button-1>",getit)

#b2 = tkinter.Button(w1,text="Entschlüsseln")
#b2.pack()

#l2 = tkinter.Label(w1,text="Malte Dev 2019")
#l2.pack()

#print(satz)
#print(verschluesselt)
# ds
#print(entschluesselt)

w1.mainloop()
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Bitte die Code Tags benutzen. Und was genau geht nicht?
Malte Dev
User
Beiträge: 4
Registriert: Sonntag 14. April 2019, 11:18

Ich müsste die Verschlüsselung ausgeben. Allerdings geht das nicht. PS: Ja, habe das mit den Code-Tags vergessen :D
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst. Daraus folgt das Funktionen (und Methoden) alles was sie ausser Konstanten benötigen per Argument(e) übergeben bekommen. Das erfordert dann wiederum entweder Closures, zum Beispiel mittels `functools.partial()` oder objektorientierte Programmierung (OOP). Ohne OOP kommt man bei der GUI-Programmierung nicht wirklich aus. Du solltest also lernen wie das funktioniert. Eventuell erst einmal ohne GUI.

An der Namensgebung solltest Du arbeiten. Einbuchstabige Namen, (unsinnig) nummerierte Namen, kryptische Abkürzungen sind alles Sachen die man vermeiden sollte. Namen sollen dem Leser vermitteln was der Wert hinter dem Namen im Kontext des Programms für eine Bedeutung hat. Ohne das der Leser viel raten muss.

Wenn man bei Schaltflächen mit `bind()` arbeitet, verhalten die sich nicht wie der Benutzer das erwartet, also nicht so wie alle anderen Schaltflächen in anderen Programmen. `Button` kennt die `command`-Option um eine Rückruffunktion/-methode anzugeben.

`verschluessele()` und `entschluessele()` enthalten fast den selben Code. Das sollte man in eine Funktion heraus ziehen, bei der die Unterschiede über die Argumente ausgedrückt werden.

Der Code ist fehlerhaft, weil man damit zu Werten kommen kann, die keine gültigen Werte für Codepoints sind. Selbst wenn man diesen Fall nicht trifft, kann man verschlüsselte Werte erhalten die man nur durch kopieren und einfügen irgend wo anders hin bekommen kann, und selbst dabei könnte ich mir vorstellen, das es Probleme geben könnte. Beispielweise wenn man auf einen oder mehrere Unicode-Zeichen endet, die nicht für sich alleine stehen können, sondern ein Zeichen danach benötigen welches sie verändern. Beispielsweise einen Accent ohne Zeichen auf dem dieser Accent gesetzt werden soll.

Zeichenketten durch wiederholtes ”addieren” zu erweitern ist ineffizient. In idiomatischem Python würde man das Ergebnis eher in einer Liste sammeln und am Ende per `join()` auf einer leeren Zeichenkette zusammenfügen.

`zeichen` ist ein irreführender Name weil der Wert gar nicht für ein Zeichen, sondern für einen Index in eine Zeichenkette steht. Indexwerte auf diese Weise sind in auch eher „unpythonisch“, denn man kann direkt über die Zeichen einer Zeichenkette iterieren. Falls man *zusätzlich* eine laufende Zahl benötigt, gibt es die `enumerate()`-Funktion. Wenn man ”parallel” über mehrere Objekte iterieren möchte, gibt es die `zip()`-Funktion. Wenn man über die Elemente eines Objekts immer wieder iterieren möchte, gibt es `itertools.cycle()` und um über aufeinanderfolgende Paare zu iterieren, gibt es in der Dokumentation von `itertools` Rezepte oder das externe `more_itertools`-Modul.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Malte Dev
User
Beiträge: 4
Registriert: Sonntag 14. April 2019, 11:18

Und wie würdest du es besser machen __blackjack__? Schreib mal den Code! (Am besten in Code-Tags)
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Malte Dev: wie man es besser macht, hat __blackjack__ ja konkret geschrieben. Was verstehst Du daran nicht?
Malte Dev
User
Beiträge: 4
Registriert: Sonntag 14. April 2019, 11:18

Naja ich möchte ja diesen Code in tkinter umwandeln:

Code: Alles auswählen

def verschluessele(s,k):
    ret = ""
    for zeichen in range(len(s)):
        ret = ret + chr(ord(s[zeichen]) + ord(k[zeichen%len(k)])-ord(k[(zeichen+1)%len(k)])+50)
    return ret
 
 
def entschluessele(s,k):
    ret = ""
    for zeichen in range(len(s)):
        ret = ret + chr(ord(s[zeichen]) - ord(k[zeichen%len(k)])+ord(k[(zeichen+1)%len(k)])-50)
    return ret
 
 
 
 
key = "geheim"
satz = "wichtiger satz"
 
verschluesselt = verschluessele(satz,key)
 
print(satz)
print(verschluesselt)
 
entschluesselt = entschluessele(verschluesselt,key)
 
print(entschluesselt)
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Malte Dev: Nein, Du möchtest das nicht, Du möchtest dass das jemand für Dich macht. ;-)

Und das beantwortet die Frage von Sirius3 nicht. Zudem könntest Du auch erst einmal Fehler beheben, denn wie gesagt kommt diese Verschlüsselung nicht mit beliebigen Schlüsseln und Texten klar. Versuch als Schlüssel einfach mal '!ü' und das ganze endet in einem `ValueError`.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Code_Bender
User
Beiträge: 21
Registriert: Sonntag 6. Januar 2019, 12:32

Ein Beispiel:
Code_Bender
User
Beiträge: 21
Registriert: Sonntag 6. Januar 2019, 12:32

from tkinter import *

Win = Tk()

En = Entry(Win)
En.pack()
En.config(show="*")

Win.mainloop()
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Und jetzt noch mal ohne Sternchen-Import, mit sinvollen Namen, die sich an die Namenskonventionen halten, ohne globale Variablen, ohne zusätzlichen `config()`-Aufruf, nur ausgeführt wenn man es ausführt und nicht wenn man es nur importiert:

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk


def main():
    window = tk.Tk()
    entry = tk.Entry(window, show='*')
    entry.pack()
    window.mainloop()


if __name__ == '__main__':
    main()
:-)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

@Code_Bender

*-Importe sind zu vermeiden weil man sich damit den Namensraum versaut.
Variablen schreibt man immer klein.
Antworten