Verschlüsseln von Buchstaben aber nicht von Zeichen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
nightm4r3^
User
Beiträge: 83
Registriert: Montag 11. Februar 2008, 15:43
Kontaktdaten:

Verschlüsseln von Buchstaben aber nicht von Zeichen

Beitragvon nightm4r3^ » Mittwoch 21. Mai 2008, 14:41

Hallo liebe Pythonleute,
ich habe eine Frage bzw auch eher ein Anliegen.
Ich bin gerade dabei ein Proramm zu schreiben mit dem man anhand von Cäsarverschlüsselung Texte verschlüsseln kann. Ich habe nur ein Problem. Ich würde gerne Alles verschlüsseln bis auf Satzzeichen und Leerzeichen. Mein erster Ansatz war das:

Code: Alles auswählen

# -*- coding: cp1252 -*-
def verschluesseln(text, versch):
    """ Verschlüsselungs-Algorithmus """

    laenge = len(text)
    versch = int(versch)%26
    text=text.upper()
    chiffre=''
    for i in range(0,laenge):
        if text[i]==' ':
            chiffre+=' '
        elif 65<=ord(text[i]) + versch<=90:
            chiffre += chr(ord(text[i])+int(versch))
        elif ord(text[i])+ versch >90:
            chiffre += chr(ord(text[i])+int(versch)-26)
        elif ord(text[i])+ versch <65:
            chiffre += chr(ord(text[i])+int(versch)+26)
       
       
     print chiffre



Das Leerzeichen ist hier schon ausgenommen. Das heißt wenn ein Leerzeichen vorhanden ist wird dieses einfach wieder mit einem Leerzeichen überschrieben. Nur wie kann ich das Nun mit Satzeichen auch noch einbauen.

PS: was ich auch noch nicht geschafft habe, ist es Groß- und Kleinschreibung zu trennen. Also wer Ideen hat, kann diese gerne Posten. Und bevor jemand fragt, JA ES IST EINE HAUSAUFGABE, ABER DIESE BESTAND NUR DARIN EIN PROGRAMM ZU SCHREIBEN DAS VERSCHLÜSSELT UND ZWAR NUR IN GRO?BUCHSTABEN UND OHNE SATZZEICHEN.
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Mittwoch 21. Mai 2008, 15:06

Also erstmal zu deiner Version. Da kann man ein wenig was verbessern:

Code: Alles auswählen

def verschluesseln2(text, versch):
    """ Verschlüsselungs-Algorithmus """

    laenge = len(text)
    versch = int(versch)%26
    text=text.upper()
    chiffre = ''
    for zeichen in text:
        if zeichen == ' ':
            chiffre += ' '
        elif 65 <= ord(zeichen) + versch <= 90:
            chiffre += chr(ord(zeichen)+versch)
        elif ord(zeichen)+ versch >90:
            chiffre += chr(ord(zeichen)+versch-26)
        elif ord(zeichen)+ versch <65:
            chiffre += chr(ord(zeichen)+versch+26)

    return chiffre


Mal eine andere Variante, die sollte mit Sonderzeichen + Groß-/Kleinschreibung zurecht kommen. Dabei werden alle nicht ASCII Zeichen einfach durchgereicht... Man könnte auch die Konstante ASCII mit Zeichen erweitern...

Code: Alles auswählen

import string
ASCII = string.ascii_letters

def verschluesseln3(text, versch):
    max_len = len(ASCII)
    chiffre = ""
    for zeichen in text:
        if not zeichen in ASCII:
            chiffre += zeichen
        else:
            pos = ASCII.index(zeichen)
            new_pos = pos + versch
            if new_pos > max_len:
                new_pos - max_len

            chiffre += ASCII[new_pos]

    return chiffre

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
EyDu
User
Beiträge: 4868
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Beitragvon EyDu » Mittwoch 21. Mai 2008, 15:09

Wäre es nicht viel einfacher, wenn du einfach angibst, welche Zeichen verschlüsselt werden sollen und alle anderen werden beibehalten? Entsprechende Konstanten für Buchstaben finden sich im "string"-Modul.

Mit

Code: Alles auswählen

for c in text: ...


kannst du übrigens direkt über die Buchstaben iterieren und sparst dir die ganzen Indizes. Die "map"-Funktion ist vielleicht auch noch ganz interessant für dich, dann musst du nicht für jeden Buchstaben einzeln "ord" und "chr" aufrufen.

Und wenn du es ganz einfach haben willst, dann verwendest du aus dem Modul "string" die Funktionen "translate" und "maketrans". In Verbindung mit Slicing ist die Aufgabe in wenigen zeilen gelöst.

Und warum regst du dich eigentlich darüber auf, dass sich jemand über deine Hausaufgaben beschweren könnte, obwohl dies noch niemand getan hat. Und so weit fortgeschritten wie deine Lösung ist, sieht man immerhin, dass du wohl verstanden hast, was du da tust.
BlackJack

Beitragvon BlackJack » Mittwoch 21. Mai 2008, 15:37

Noch ein Verbesserungsvorschlag: Nicht mit Zahlen bei den Bereichstests, sondern mit Zeichenketten arbeiten. Etwas wie:

Code: Alles auswählen

    if 'A' <= chr(ord(zeichen) + distanz) <= 'Z':


ist weniger kryptisch als:

Code: Alles auswählen

    if 65 <= ord(zeichen) + versch <= 90:


Nicht jeder hat die ASCII-Tabelle im Kopf, aber die meisten können Buchstaben lesen. :-)

Edit: Lösungsvorschlag

Code: Alles auswählen

def caesar_crypt(key, text):
    result = list()
    for character in text:
        for low, high in ('az', 'AZ'):
            if low <= character <= high:
                range_length = ord(high) - ord(low) + 1
                character = chr(((ord(character) - ord(low) + key)
                                 % range_length + ord(low)))
                break
        result.append(character)
    return ''.join(result)


def main():
    source = 'ABCD...WXYZ abcd...wxyz, Hallo Welt.'
    encrypted = caesar_crypt(10, source)
    print encrypted
    print caesar_crypt(-10, encrypted)
nightm4r3^
User
Beiträge: 83
Registriert: Montag 11. Februar 2008, 15:43
Kontaktdaten:

Beitragvon nightm4r3^ » Mittwoch 21. Mai 2008, 16:20

Also erst mal vielen Dank für die ganzen Verbesserungsvorschlläge und so, aber wer einem Greenie wie mir einen Gefallen tun will (müsst nicht wen ihr nicht wollt) wärs nett noch ein paar Hilfen (also was man damit bewirkt oder so) dabeizuposten.


Aber auf jeden fall vielen Dank
nightm4r3^
User
Beiträge: 83
Registriert: Montag 11. Februar 2008, 15:43
Kontaktdaten:

Beitragvon nightm4r3^ » Mittwoch 21. Mai 2008, 17:35

Okay ich stell mal eine direkte Frage:

Was bedeutet denn die Zeile:

Code: Alles auswählen

for low, high in ('az', 'AZ'):

Also was eine For-Schleife ist ist schon klar^^ nur habe ich noch nie eine For Schleife gesehen, in der 2. Zählvariablen (low, high) drin vorkommen. Könnte mir das vllt mal jemand erklären?
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Mittwoch 21. Mai 2008, 17:38

Was gibt es da zu erklären, teste einfach den Code:

Code: Alles auswählen

for one, two in ((1, 2), (3, 4), (5, 6), (7, 8)):
    print one, two
My god, it's full of CARs! | Leonidasvoice vs Modvoice
EyDu
User
Beiträge: 4868
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Beitragvon EyDu » Mittwoch 21. Mai 2008, 19:26

Na dann will ich doch auch mal:

Code: Alles auswählen

from string import ascii_lowercase as LOW, ascii_uppercase as UP

def caesar_crypt(key, text):
    def rotate(x):
        return x[key:]+x[:key]
   
    table = string.maketrans(LOW+UP, rotate(LOW)+rotate(UP))
    return string.translate(text, table)
lunar

Beitragvon lunar » Mittwoch 21. Mai 2008, 21:07

Was mich jetzt interessiert: Wäre ``Hello World'.encode('rot13')`` als Lösung akzeptabel gewesen?
nightm4r3^
User
Beiträge: 83
Registriert: Montag 11. Februar 2008, 15:43
Kontaktdaten:

Beitragvon nightm4r3^ » Donnerstag 22. Mai 2008, 10:09

ja leonidas das hab ich als aller erstes gemacht. Trotzdem weiß ich immer noch nicht was es bringt, wenn das Programm

Code: Alles auswählen

'a   A'
'z   Z'

ausgibt.
BlackJack

Beitragvon BlackJack » Donnerstag 22. Mai 2008, 11:10

Welches Programm macht das!? Kann es sein, dass Du das mit Namen und Objekten, manchmal auch Variablen genannt, *immer* noch nicht begriffen hast!?
nightm4r3^
User
Beiträge: 83
Registriert: Montag 11. Februar 2008, 15:43
Kontaktdaten:

Beitragvon nightm4r3^ » Donnerstag 22. Mai 2008, 13:11

Ja das kann schon sein aber wie soll ich was lernen wenn ich keine Hilfe bekomme verdammt. Von den Administratoren hier bekommt man nämlich nur Nörgeleien ab und nichts brauchbares.
BlackJack

Beitragvon BlackJack » Donnerstag 22. Mai 2008, 13:51

Ich weiss nicht ob man jemandem in einem Forum denken und das zum Programmieren nötigen Abstraktionsvermögen so einfach näherbringen kann.

Das was Leonidas da gezeigt hat ist eine ziemlich einfache Schleife und wenn Du da den Zusammenhang zwischen den Tupeln, den beiden Namen, und was in der Schleife dann an die Namen gebunden ist, nicht verstehst, dann weiss ich ehrlich gesagt nicht, wie man da noch weiter helfen könnte ausser Dir eine fertige Lösung vor zu setzen. Aber warte, genau die gibt es hier ja auch schon in dem Thread.
Benutzeravatar
wuf
User
Beiträge: 1408
Registriert: Sonntag 8. Juni 2003, 09:50

Beitragvon wuf » Donnerstag 22. Mai 2008, 22:59

Hallo Forumfreunde

Erstmals ein herzliches Dankeschön an Leonidas, BlackJack
und alle Forummitglieder die uns immer grosszügig und ge-
duldig, bei unseren manchmal aufreibenden Fragen unterstützen!
In der heutigen Zeit ist dies nicht selbstverständlich.

Ich persönlich finde BlackJack's Code-Optimierung der
Ceasar-Verschlüsselung einfach genial und sehr lehrreich.

Ich beschäftige mich nun schon bald fünf Jahre mit der Python
und Tkinter Programmierung. Muss aber immer wieder feststellen,
dass ich noch lange nicht alles weiss. Das zeigen immer wieder
die interessanten Beiträge in unserem Forum. Auch beim durchlesen
der massenhaft zur Verfügung stehenden Bibliotheken zeigt sich
immer wieder, dass eigentlich vieles schon fix und fertig verfügbar
wäre. Sachen welche die man versucht mühsam selber zu program-
mieren. Es braucht aber auch viel Zeit all die Literatur zu durch-
stöbern um das gewünschte zu finden. Da wird schnell einmal das
Problem mit Learning by doing gelöst. Damit entsteht auch Code
der nicht optimal ist. Man ist zufrieden, wenn der Input den
gwünschten Output ergibt.

An nightm4r3^

Nicht aufgeben!!! Auch wir alle haben einmal angefangen, so auch
unser Forumfreunde Leonidas und BlackJack. Du kannst ja ein Filter-
programm programmieren (natürlich in Python), welches unbeliebte
Ausdrücke bzw. Textfolgen eliminiert und damit den Forumtext vor
der Interpretierung entschärfen Hi.

Ich hatte einige Minuten freie Zeit um den optimierten Code
von BlackJack mit Kommentar zu ergänzen und hoffe den Code
richtig interpretiert zu haben:

[Code ausgelagert]

Gruss wuf :wink:

Edit (Leonidas): Code ausgelagert, da der Thread schon fast blockiert hat.
Take it easy Mates!
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Donnerstag 22. Mai 2008, 23:11

Im Thread Caesar-Veschlüsselung ist so etwas auch noch mal implementiert, dort gibt es auch eine Lösung mit einem Ringspeicher. Die könnte man natürlich auch so modifizieren, dass sie unbekannte Zeichen in Ruhe lässt.
My god, it's full of CARs! | Leonidasvoice vs Modvoice

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot]