QLineEdit und SHA-Hash

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Phollux
User
Beiträge: 3
Registriert: Mittwoch 18. Dezember 2013, 19:50

Hallo zusammen,

Ich habe ein kleines Problem mit QLineEdit.

Nehmen wir an, der Inhalt des QLineEdit-Feldes wäre 'benutzername'.

Vergleiche ich nun QLineEdit.text() mit dem string 'benutzername', so erhalte ich ein True. Macht ja auch Sinn, steht ja dasselbe drin. :P

Wenn ich nun aber den QLineEdit.text() mit SHA256 hashe und dann mit dem SHA256-gehashtem string vergleiche, so erhalte ich ein False. Was mich eben verwundert. :(

Zum hashen verwende ich folgendes:

Code: Alles auswählen

from Crypto.Hash import SHA256
sha_key = SHA256
sha_key.new(string).hexdigest()
Kann mir einer sagen, ob bei QLineEdit vielleicht noch irgendetwas angehangen wird, was nicht angezeigt wird? ein str(QLineEdit.text()) scheint jedenfalls nicht erfolgsversprechend. :K

Wäre cool, wenn Jemand darauf eine Antwort hätte.

MfG
Phollux
BlackJack

@Phollux: Ich wette Du machst in dem Quelltext den Du nicht zeigst irgendwas falsch. Müssen wir jetzt raten wie Dein Quelltext aussieht? ;-)
Phollux
User
Beiträge: 3
Registriert: Mittwoch 18. Dezember 2013, 19:50

Hallo,

Entschuldige, ich wollte das ganze nicht unnötig verkomplizieren. Scheinbar aber habe ich genau das getan. :D
Ich stell hier mal einen kleinen Beispielcode rein, um zu zeigen, was ich meine.

Code: Alles auswählen

# -*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui
from Crypto.Hash import SHA256

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName(_fromUtf8("Dialog"))
        Dialog.resize(400, 300)
        self.pushButton = QtGui.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(130, 60, 99, 23))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton.clicked.connect(self.vergleicher)
        self.lineEdit = QtGui.QLineEdit(Dialog)
        self.lineEdit.setGeometry(QtCore.QRect(120, 10, 113, 22))
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
        self.label = QtGui.QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(16, 120, 361, 20))
        self.label.setObjectName(_fromUtf8("label"))

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(_translate("Dialog", "Dialog", None))
        self.pushButton.setText(_translate("Dialog", "PushButton", None))
        self.label.setText(_translate("Dialog", "TextLabel", None))

    def vergleicher(self):
        sha_1 = SHA256
        sha_2 = SHA256
        self.label.setText(str(sha_1.new(self.lineEdit.text()).hexdigest() == sha_2.new('string').hexdigest()))
        
if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    Dialog = QtGui.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())
lunar

@Phollux Hast Du da wirklich den Quelltext, den der Qt Designer erzeugt, editiert?
BlackJack

@Phollux: Da ist dann jetzt also die Frage was `Crypto.SHA256` mit einem `QString`-Objekt macht. Das solltest Du vielleicht in eine Bytezeichenkette umwandeln bevor Du es übergibst. Sonst stellt sich ja auch gleich das nächste Problem: Was passiert mit Eingaben die Zeichen ausserhalb von ASCII enthalten.

Gibt es eigentlich einen Grund warum Du nicht `hashlib.sha256` aus der Standardbibliothek vewendest? Und warum zur Hölle bindest Du `Crypto.SHA256` unnötigerweise an die Namen `sha_1` und `sha_2`?
Benutzeravatar
Madmartigan
User
Beiträge: 200
Registriert: Donnerstag 18. Juli 2013, 07:59
Wohnort: Berlin

Code: Alles auswählen

# -*- coding: utf-8 -*-
...
        self.label.setText(str(sha_1.new(self.lineEdit.text()).hexdigest() == sha_2.new('string').hexdigest()))
...
In der Zeile steckt bereits ein potentieller Kandidat. Dem Aufruf sha_1.ew(string) wird hier ein QString übergeben. Das geht i.d.R. schief. Danach bringt auch str() nicht wirklich etwas.
Sind denn SHA256.new() und hexdigest() wirklich in-place verwendbar?

lunar hat geschrieben:@Phollux Hast Du da wirklich den Quelltext, den der Qt Designer erzeugt, editiert?
Welchen Teil des Codes meinst du denn, ich kann nicht erkennen, dass QtDesigner verwendet wurde. Er lädt doch nirgends ein *.ui file.
BlackJack

@Madmartigan: Wieso sollte `hexdigest()` nicht „in place” verwendbar sein? Das ist Python und nicht PHP! :-)

lunar meint den gezeigten Quelltext. Der sieht aus als wäre er vom Designer generiert und dann bearbeitet worden. Natürlich ist dann da auch keine *.ui-Datei mehr im Spiel.
Benutzeravatar
Madmartigan
User
Beiträge: 200
Registriert: Donnerstag 18. Juli 2013, 07:59
Wohnort: Berlin

Das war mir eben unklar, ich kenne Crypto.Hash nicht, weiß daher auch nicht, was da intern geschieht. War nur ein Gedanke...

Wie Code, erstellt vom QtDesigner, ausschaut, weiß ich nicht, nutze ihn nicht. Ist es nun ein positives Merkmal, dass man den Code als solchen erkennen kann, oder eher ein negatives?
BlackJack

@Madmartigan: Dazu braucht man `Crypto.Hash` nicht kennen, wenn es nicht-„in place” geht, dann geht es auch „in place”. Das ist grundlegende Python-Syntax, die ist völlig unabhängig vom konkreten Code den man da verwendet.

Es geht nicht um das erkennen können, sondern das der *verändert* wurde. Damit kann man nichts mehr mit dem Designer an der UI ändern, weil ein erneutes generieren ja nicht nur den vorher generierten Quelltext überschreibt, sondern auch die Änderungen. Das ist irgendwie keine so gute Idee. Die generierten Dateien sind zum importieren und „beerben” gedacht, wie das eigentlich auch in der Dokumentation und Tutorials üblicherweise gezeigt wird.

Ich perönlich finde generierten Quelltext an der Stelle nicht schön. Das ist ein zusätzlicher Schritt beim bauen oder aktualisieren einer Anwendung, den man sich durch dynamisches laden der *.ui-Datei sparen kann.
Phollux
User
Beiträge: 3
Registriert: Mittwoch 18. Dezember 2013, 19:50

Hallo,
@Phollux Hast Du da wirklich den Quelltext, den der Qt Designer erzeugt, editiert?
Ja. Ich weiß, ist schmutzig. Aber dient hier eigentlich auch nur der Demonstration. :lol:
In der Zeile steckt bereits ein potentieller Kandidat. Dem Aufruf sha_1.ew(string) wird hier ein QString übergeben. Das geht i.d.R. schief.
Stimmt, danke sehr. Das war dann auch des Rätsels Lösung. :D
Man ersetze Zeile 46 wie folgt:

Code: Alles auswählen

self.label.setText(str(sha_1.new(str(self.lineEdit.text())).hexdigest() == sha_2.new('string').hexdigest()))

Okay, danke für die ganzen Hilfeversuche! :)

Lg,
Phollux
Benutzeravatar
Madmartigan
User
Beiträge: 200
Registriert: Donnerstag 18. Juli 2013, 07:59
Wohnort: Berlin

BlackJack hat geschrieben:...wenn es nicht-„in place” geht, dann geht es auch „in place”....
Der Satz ist mir unverständlich.

Ich kann mich erinnern, dass es z.B. bei Listensortierung Unterschiede bei den Operationen gibt, Manche sind nicht in-place verwendbar. Vielleicht ist mein Gedächtnis aber auch fehlerhaft. Ich werde mich noch mal belesen, will hier nicht zu viel OT produzieren.
BlackJack

@Madmartigan: Ich meinte damit

Code: Alles auswählen

# wenn das geht:
spam = Ham()
parrot = spam.frobnicate()
# kann man das auch immer so schreiben:
parrot = Ham().frobnicate()
Und der Umkehrschluss gilt natürlich auch, darum machte Deine Frage für mich keinen Sinn.

Mit Listen meinst Du wahrscheinlich das `sort()` die Liste nicht zurück gibt. Da ist doch aber eine ganz andere Situation, da wird ja weder ein Objekt erzeugt, noch ein Wert abgefragt, sondern der interne Zustand verändert.
Benutzeravatar
Madmartigan
User
Beiträge: 200
Registriert: Donnerstag 18. Juli 2013, 07:59
Wohnort: Berlin

Die Instanzierung von Ham() ist ja hier dann auch in-place. Genau das meinte ich mit der Frage bzgl. SHA256.new() und hexdigest(). Vielleicht hätte ich es anders formulieren und fragen sollen, ob an der Stelle denn auch wirklich eine Rückgabe steht oder nicht.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

BlackJack hat geschrieben: Ich perönlich finde generierten Quelltext an der Stelle nicht schön. Das ist ein zusätzlicher Schritt beim bauen oder aktualisieren einer Anwendung, den man sich durch dynamisches laden der *.ui-Datei sparen kann.
Da ich seit über einem Jahr nichts mehr mit Qt gemacht habe: Kann PySide denn mittlerweile GUIs aus ui-Dateien dynamisch generieren? Das war eine Sache, die PyQt ersterem leider noch voraus hatte...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

@Hyperion: Das ging seit dem ersten Release von PySide schon…
BlackJack

@apollo13: Ich denke Hyperion meint das `uic`-Modul und das gibt es AFAIK für PySide immer noch nicht.
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

@BlackJack: Ich habe den Sinn davon noch nie gesehen, es gibt QUiLoader und der Rest herum ist fünf Zeilen; selbst mein CPP Code lädt UI Files dynamisch :)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

apollo13 hat geschrieben:@BlackJack: Ich habe den Sinn davon noch nie gesehen, es gibt QUiLoader und der Rest herum ist fünf Zeilen; selbst mein CPP Code lädt UI Files dynamisch :)
Ich will aber keine *fünf* Zeilen, sondern im Idealfall *keine* oder maximal *eine* ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten