Finde den Fehler in einfachem Verschlüsselungstool nicht

  • Hallo miteinander.
    Ich bin Leiter bei den Pfadfindern und habe mit meinen Kids (7-10 Jahre alt) vor ein paar Wochen Geheimschriften in der Gruppenstunde gemacht. Das ganz einfache "um x Buchstabven verschieben"-Teil.
    Das hat den Kids gut gefallen, und ich wollte eine Ausschreibung für eine anstehende Veranstaltung nun verschlüsselt in der Gruppenstunde rausgeben. Damit das ganze ein bisschen interessanter ist, will ich die Verschiebung wortweise mit einem zufällig gewählten Wert machen. "Mein" Algorithmus müsste anhand des kommentierten Quellcodes verständlich sein. Allerdings bin ich mit dem Output nicht so glücklich, funktioniert nicht so ganz wie gewünscht :(
    Findet jemand zufällig den Fehler? Syntaxfehler waren diesesmal von Anfang an (mal abgesehen von einer falsch geschriebenen Variable) keine drin *freu*, aber den Logikfehler/die Logikfehler finde ich trotzdem nicht...

    Hier nun der Quellcode:

    Spoiler anzeigen
    [autoit]

    #cs ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    AutoIt Version: 3.3.9.4 (beta)
    Author: Weisgarnix

    [/autoit] [autoit][/autoit] [autoit]

    #ce ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    #include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <Array.au3>
    #Region ### START Koda GUI section ### Form=
    $Form1 = GUICreate("Form1", 615, 438, 192, 124)
    $Edit1 = GUICtrlCreateEdit("", 16, 16, 577, 369)
    GUICtrlSetData(-1, "Edit1")
    $Button1 = GUICtrlCreateButton("Button1", 232, 408, 105, 25)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###

    [/autoit] [autoit][/autoit] [autoit]

    Dim $smalllettersarray[27]
    Dim $biglettersarray[27]

    [/autoit] [autoit][/autoit] [autoit]

    $smalllettersarray[1]="a"
    $smalllettersarray[2]="b"
    $smalllettersarray[3]="c"
    $smalllettersarray[4]="d"
    $smalllettersarray[5]="e"
    $smalllettersarray[6]="f"
    $smalllettersarray[7]="g"
    $smalllettersarray[8]="h"
    $smalllettersarray[9]="i"
    $smalllettersarray[10]="j"
    $smalllettersarray[11]="k"
    $smalllettersarray[12]="l"
    $smalllettersarray[13]="m"
    $smalllettersarray[14]="n"
    $smalllettersarray[15]="o"
    $smalllettersarray[16]="p"
    $smalllettersarray[17]="q"
    $smalllettersarray[18]="r"
    $smalllettersarray[19]="s"
    $smalllettersarray[20]="t"
    $smalllettersarray[21]="u"
    $smalllettersarray[22]="v"
    $smalllettersarray[23]="w"
    $smalllettersarray[24]="x"
    $smalllettersarray[25]="y"
    $smalllettersarray[26]="z"

    [/autoit] [autoit][/autoit] [autoit]

    $biglettersarray[1]="A"
    $biglettersarray[2]="B"
    $biglettersarray[3]="C"
    $biglettersarray[4]="D"
    $biglettersarray[5]="E"
    $biglettersarray[6]="F"
    $biglettersarray[7]="G"
    $biglettersarray[8]="H"
    $biglettersarray[9]="I"
    $biglettersarray[10]="J"
    $biglettersarray[11]="K"
    $biglettersarray[12]="L"
    $biglettersarray[13]="M"
    $biglettersarray[14]="N"
    $biglettersarray[15]="O"
    $biglettersarray[16]="P"
    $biglettersarray[17]="Q"
    $biglettersarray[18]="R"
    $biglettersarray[19]="S"
    $biglettersarray[20]="T"
    $biglettersarray[21]="U"
    $biglettersarray[22]="V"
    $biglettersarray[23]="W"
    $biglettersarray[24]="X"
    $biglettersarray[25]="Y"
    $biglettersarray[26]="Z"

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

    [/autoit] [autoit][/autoit] [autoit]

    Case $Button1
    ClipPut(_encrypt(GUICtrlRead($Edit1)))
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _encrypt($input)
    ; Output-Variable, wird nach und nach gefüllt...
    $output=""
    ; Es werden einzelne Wörter verschlüsselt.
    $words=StringSplit($input, " ")
    ; Wortlänge in einer normalen Variable zur einfacheren Verwendung
    $wordssize=$words[0]
    ; Für jedes Wort, tue folgendes:
    For $wordscount=1 To $wordssize
    ; Zerlege das Wort in seine einzelnen Buchstaben/Zeichen
    $letters=StringSplit($words[$wordscount], "")
    ; Anzahl der Zeichen in einer normalen Variable zur einfacheren Verwendung
    $letterssize=$letters[0]
    ; Verschlüsselungszahl (Um wie viel die Buchstaben dieses Wortes im Alphabet verschoben sind)
    $key=Random(1, 26, 1)
    ; Für jeden einzelnen Buchstaben / jedes einzelne Zeichen, tue folgendes:
    For $everysingleletter=1 To $letterssize
    ; Standartwertsetzung...
    $currentletterisbig=False
    $currentletterissmall=False
    ; Ermitteln der aktuellen Position des Buchstaben im Großbuchstabenarray
    $position=_ArraySearch($biglettersarray, $letters[$everysingleletter], 1, $letterssize, 1)
    ; Aktuelles Zeichen kein Großbuchstabe
    If $position=-1 Then
    ; Ermitteln der aktuellen Position des Buchstaben im Kleinbuchstabenarray
    $position=_ArraySearch($smalllettersarray, $letters[$everysingleletter], 1, $letterssize, 1)
    ; Falls im Kleinbuchstabenarray auch nicht vorhanden, dann...
    If $position=-1 Then
    ; ... lassen wir die oben vergebenen Default-Werte so stehen
    Else
    ; Falls vorhanden, setzen wir die Variable einfach auf True
    $currentletterissmall=True
    EndIf
    Else
    ; Test für Großbuchstabe war positiv, also setzen wir die Variable auf True
    $currentletterisbig=True
    EndIf
    ; Initialisierung, wie oft schon verschoben wurde
    $slide=0
    ; Solange noch nicht oft genug verschoben wurde, tue folgendes:
    While $slide<$key
    ; Positionsumsetzung, falls die aktuelle Position 0 wäre...
    If $position=0 Then
    $position=26
    EndIf
    ; Wir ändern den Positionswert um 1 ...
    $position-=1
    ; ... und merken uns, dass wir ihn um eine weitere Position verändert haben
    $slide+=1
    WEnd
    ; Nun kommt die Auswertung der obigen Verschiebereien...
    If $currentletterisbig Then
    $output&=$biglettersarray[$position]
    EndIf
    If $currentletterissmall Then
    $output&=$smalllettersarray[$position]
    EndIf
    ; Falls das aktuelle Zeichen in keinem der beiden Arrays gefunden wurde, machen wir gar nichts mit ihm
    If Not ($currentletterisbig or $currentletterissmall) Then
    $output&=$letters[$everysingleletter]
    EndIf
    Next
    ; Am Ende des Wortes hängen wir den Großbuchstaben dran, der an §key-Stelle im Alphabet steht...
    $output&=$biglettersarray[$key]
    ; ... und hängen das trennende Leerzeichen an
    $output&=" "
    ; Das widerholen wir nun noch mit den anderen Wörtern...
    Next
    ; Und am Ende geben wir das Ergebnis der Bastelei zurück...
    Return $output
    EndFunc

    [/autoit]

    *Edit* Hier das kommt z.B. raus, was aber falsch ist:
    [Eingabe]Hallo Weisgarnix!
    [Ausgabe]HhlloS Wswsuornwx!L
    Mit einzelnen Buchstaben scheint es zu tun, komischerweise, aber mit einzelnen auch wieder nicht. Bin ratlos :(
    PS: Bei den verschobenen Buchstaben scheint die Verschiebung zu stimmen, bei den nciht verschobenen stimmt sie natürlich nicht.

    3 Mal editiert, zuletzt von Weisgarnix (29. November 2012 um 21:48) aus folgendem Grund: Gelöst ;)

  • Wenn ich dich richtig verstanden habe, dann mußt die Schleife so aussehen

    [autoit]

    While $slide < $key
    ; Wir ändern den Positionswert um 1 ...
    $position -= 1
    ; Positionsumsetzung, falls die aktuelle Position 0 wäre...
    If $position = 0 Then
    $position = 26
    EndIf
    ; ... und merken uns, dass wir ihn um eine weitere Position verändert haben
    $slide += 1
    WEnd

    [/autoit]
  • Du hast zuerst die Position verändert (Sollte ja zu Beginn nicht 0 sein, also geht das) und dann erst geprüft, ob es nun auf 0 stünde.
    Sollte ergal sein, in welcher Reihenfolge das geschieht, und leider sieht Autoit das genauso:
    Ergebnis bei Eingabe "Hallo!": Hcllo!X
    Das c und das X stimmen, der Rest leiter nicht :(

  • Wuhu! Hatte zuerst darauf getippt, dass da was mit meiner Benutzung von _ArraySearch nicht stimmt. Aber das mache ich alles richtig.
    Fehler lag hier:

    [autoit]

    $position=_ArraySearch($biglettersarray, $letters[$everysingleletter], 1, 26, 1) ; Wir sollten das Array schon bis zum Ende und nicht bis zu $letterssize durchsuchen!!!
    ; Aktuelles Zeichen kein Großbuchstabe
    If $position=-1 Then
    ; Ermitteln der aktuellen Position des Buchstaben im Kleinbuchstabenarray
    $position=_ArraySearch($smalllettersarray, $letters[$everysingleletter], 1, 26, 1) ; Same Story hier auch...^^

    [/autoit]


    Ergebnis bei Hallo!:
    Exiil!C
    Das komplette Script, nun kann es auch zeilenumbrüche, falls es jemand auch noch gebrauchen kann:

    Spoiler anzeigen
    [autoit]

    #cs ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    AutoIt Version: 3.3.9.4 (beta)
    Author: myName

    [/autoit] [autoit][/autoit] [autoit]

    Script Function:
    Template AutoIt script.

    [/autoit] [autoit][/autoit] [autoit]

    #ce ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    ; Script Start - Add your code below here

    [/autoit] [autoit][/autoit] [autoit]

    #include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <Array.au3>
    #Region ### START Koda GUI section ### Form=
    $Form1 = GUICreate("Form1", 615, 438, 192, 124)
    $Edit1 = GUICtrlCreateEdit("", 16, 16, 577, 369)
    GUICtrlSetData(-1, "Edit1")
    $Button1 = GUICtrlCreateButton("Button1", 232, 408, 105, 25)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###

    [/autoit] [autoit][/autoit] [autoit]

    Dim $smalllettersarray[27]
    Dim $biglettersarray[27]

    [/autoit] [autoit][/autoit] [autoit]

    $smalllettersarray[1]="a"
    $smalllettersarray[2]="b"
    $smalllettersarray[3]="c"
    $smalllettersarray[4]="d"
    $smalllettersarray[5]="e"
    $smalllettersarray[6]="f"
    $smalllettersarray[7]="g"
    $smalllettersarray[8]="h"
    $smalllettersarray[9]="i"
    $smalllettersarray[10]="j"
    $smalllettersarray[11]="k"
    $smalllettersarray[12]="l"
    $smalllettersarray[13]="m"
    $smalllettersarray[14]="n"
    $smalllettersarray[15]="o"
    $smalllettersarray[16]="p"
    $smalllettersarray[17]="q"
    $smalllettersarray[18]="r"
    $smalllettersarray[19]="s"
    $smalllettersarray[20]="t"
    $smalllettersarray[21]="u"
    $smalllettersarray[22]="v"
    $smalllettersarray[23]="w"
    $smalllettersarray[24]="x"
    $smalllettersarray[25]="y"
    $smalllettersarray[26]="z"

    [/autoit] [autoit][/autoit] [autoit]

    $biglettersarray[1]="A"
    $biglettersarray[2]="B"
    $biglettersarray[3]="C"
    $biglettersarray[4]="D"
    $biglettersarray[5]="E"
    $biglettersarray[6]="F"
    $biglettersarray[7]="G"
    $biglettersarray[8]="H"
    $biglettersarray[9]="I"
    $biglettersarray[10]="J"
    $biglettersarray[11]="K"
    $biglettersarray[12]="L"
    $biglettersarray[13]="M"
    $biglettersarray[14]="N"
    $biglettersarray[15]="O"
    $biglettersarray[16]="P"
    $biglettersarray[17]="Q"
    $biglettersarray[18]="R"
    $biglettersarray[19]="S"
    $biglettersarray[20]="T"
    $biglettersarray[21]="U"
    $biglettersarray[22]="V"
    $biglettersarray[23]="W"
    $biglettersarray[24]="X"
    $biglettersarray[25]="Y"
    $biglettersarray[26]="Z"

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

    [/autoit] [autoit][/autoit] [autoit]

    Case $Button1
    ClipPut(_encrypt(GUICtrlRead($Edit1)))
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _encrypt($input)
    ; Output-Variable, wird nach und nach gefüllt...
    $output=""
    ; Es werden einzelne Wörter verschlüsselt.
    $linefeeds=StringSplit($input, @LF)
    For $currentlinefeed=1 To $linefeeds[0]
    $words=StringSplit($linefeeds[$currentlinefeed], " ")
    ; Wortlänge in einer normalen Variable zur einfacheren Verwendung
    $wordssize=$words[0]
    ; Für jedes Wort, tue folgendes:
    For $wordscount=1 To $wordssize
    ; Zerlege das Wort in seine einzelnen Buchstaben/Zeichen
    $letters=StringSplit($words[$wordscount], "")
    ; Anzahl der Zeichen in einer normalen Variable zur einfacheren Verwendung
    $letterssize=$letters[0]
    ; Verschlüsselungszahl (Um wie viel die Buchstaben dieses Wortes im Alphabet verschoben sind)
    $key=Random(1, 26, 1)
    ; Für jeden einzelnen Buchstaben / jedes einzelne Zeichen, tue folgendes:
    For $everysingleletter=1 To $letterssize
    ; Standartwertsetzung...
    $currentletterisbig=False
    $currentletterissmall=False
    ; Ermitteln der aktuellen Position des Buchstaben im Großbuchstabenarray
    $position=_ArraySearch($biglettersarray, $letters[$everysingleletter], 1, 26, 1)
    ; Aktuelles Zeichen kein Großbuchstabe
    If $position=-1 Then
    ; Ermitteln der aktuellen Position des Buchstaben im Kleinbuchstabenarray
    $position=_ArraySearch($smalllettersarray, $letters[$everysingleletter], 1, 26, 1)
    ; Falls im Kleinbuchstabenarray auch nicht vorhanden, dann...
    If $position=-1 Then
    ; ... lassen wir die oben vergebenen Default-Werte so stehen
    Else
    ; Falls vorhanden, setzen wir die Variable einfach auf True
    $currentletterissmall=True
    EndIf
    Else
    ; Test für Großbuchstabe war positiv, also setzen wir die Variable auf True
    $currentletterisbig=True
    EndIf
    ; Initialisierung, wie oft schon verschoben wurde
    $slide=0
    ; Solange noch nicht oft genug verschoben wurde, tue folgendes:
    While $slide<$key
    ; Wir ändern den Positionswert um 1 ...
    $position-=1
    ; Positionsumsetzung, falls die aktuelle Position 0 wäre...
    If $position=0 Then
    $position=26
    EndIf
    ; ... und merken uns, dass wir ihn um eine weitere Position verändert haben
    $slide+=1
    WEnd
    ; Nun kommt die Auswertung der obigen Verschiebereien...
    If $currentletterisbig Then
    $output&=$biglettersarray[$position]
    EndIf
    If $currentletterissmall Then
    $output&=$smalllettersarray[$position]
    EndIf
    ; Falls das aktuelle Zeichen in keinem der beiden Arrays gefunden wurde, machen wir gar nichts mit ihm
    If Not ($currentletterisbig or $currentletterissmall) Then
    $output&=$letters[$everysingleletter]
    EndIf
    Next
    ; Am Ende des Wortes hängen wir den Großbuchstaben dran, der an §key-Stelle im Alphabet steht...
    $output&=$biglettersarray[$key]&" "
    ; Das widerholen wir nun noch mit den anderen Wörtern...
    Next
    ; Hier müssen wir den LineFeed wieder hinzu fügen...
    $output&=@CRLF
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ; Und am Ende geben wir das Ergebnis der Bastelei zurück...
    Return $output
    EndFunc

    [/autoit]


    Sry, dass hier nun welche vielleicht unnötig Zeit investiert haben, hatte vor dem posten schon eine halbe Stunde lang den Code durchforstet, aber erst eben fiel es mir wie Schuppen von den Augen...

    Einmal editiert, zuletzt von Weisgarnix (29. November 2012 um 22:37)