Seite 1 von 1

Caesar Code Variante

Verfasst: Donnerstag 19. März 2009, 20:13
von INFACT
Sehr geehrtes Python Forum,
ich versuche gerade eine CaesarCode Variante zu Programmieren, die man z.B. mit "abcdefg"(ord("a"),ord("b")...) verschlüsseln kann, damit man nicht nur 26 mal ausprobieren muss.
Leider gelingt mir das nicht so ganz, da ich immer irgenteinen Zahlenwirrwar herausbekomme.
Kann mir jemand weiterhelfen?

Danke für Antworten.

MfG Robin :wink:

Verfasst: Donnerstag 19. März 2009, 20:21
von derdon
Wenn du mit Caesar Code ROT13 meinst, dann ist das in Python ganz einfach:

Code: Alles auswählen

In [313]: import string

In [314]: string.ascii_letters
Out[314]: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

In [315]: string.ascii_letters.encode('rot13')
Out[315]: 'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM'

In [316]: string.ascii_letters.encode('rot13').encode('rot13')
Out[316]: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
Zum selber implementieren die Suche benutzen oder einfach recherchieren/nachdenken.

Verfasst: Donnerstag 19. März 2009, 20:26
von INFACT
So verschiebe ich das aber immer um 13 Stellen.
Ich möchte es aber so haben, dass man es mehrmals um verschiedene Stellen verschiebt

Verfasst: Donnerstag 19. März 2009, 21:26
von BlackJack
@INFACT: Wie meinst Du das genau? Wenn Du einmal um `a` Stellen verschiebst und dann noch einmal um `b` Stellen, ist das das gleiche wie *einmal* um `a+b` Stellen zu verschieben. Damit hast Du also nichts gewonnen.

Verfasst: Freitag 20. März 2009, 16:14
von INFACT
Kann sein, dass das ich das nicht richtig erkärt habe, ich meine ich, verschlüssele das um "a" und dann verschiebe ich das um a, also, wenn a=1 ist verschiebe ich das so:
"abcd"
"bcde" und dann verschieben
"cdeb"

Verfasst: Freitag 20. März 2009, 16:30
von yipyip
Du suchst wohl einfach nur das hier:

Code: Alles auswählen

def rotate(seq, n):
  
  m = n % len(seq)
  return seq[m:] + seq[:m]


print rotate('abcd', -1)
ls = [rotate('abcdefg', i) for i in range(9)]
for i in ls:
  print i
:wink:
yipyip

Verfasst: Freitag 20. März 2009, 16:30
von Hyperion
INFACT hat geschrieben:Kann sein, dass das ich das nicht richtig erkärt habe,
Was nun folgt kann gar nicht "richtiger" sein :twisted:
ich meine ich, verschlüssele das um "a"
Was meint "verschlüsseln"?
und dann verschiebe ich das um a
Ok, das war einleuchtend.
, also, wenn a=1 ist verschiebe ich das so:
Ich dachte erst wird "verschlüsselt"? Oder ist "verschlüsseln" nun doch einfach "verschieben"?
"abcd"
"bcde" und dann verschieben
"cdeb"
Ok, daran kann man erkennen, was Du willst ... wenn man scharf hinguckt ;-)

Du meinst folgendes:
1.) Verschiebe jeden Buchstaben des Inputs um x Stellen im gegebenen Ausgangsalphabet.
2.) Rotiere den verschlüsselten Text um y Stellen.

So richtig?

Verfasst: Freitag 20. März 2009, 17:01
von INFACT
T'schuldigung ich kann nicht so richtig erklären:cry: :wink: :wink:
Ja das ist richtig *gins*
Aber mein eigentliches Problem ist das hier:

Code: Alles auswählen

def turn(seq, i):
	end=""
	for j in seq:
		code=(ord(j)+ord(i))
		if code>255:
			code-=255
		end=end+chr(code)
	return end

>>> turn("abc","a")
'\xc2\xc3\xc4'
eigentlich sollte da jetzt bcd stehen... :?:

Verfasst: Freitag 20. März 2009, 17:19
von EyDu
Dann schau dir mal den Wert von ord("a") an, vielleicht kommst du dann auf deinen Fehler ;-)

Edit: Mit "string.maketrans" und "str.translate" ist es sicher einfacher.

Verfasst: Freitag 20. März 2009, 17:25
von Hyperion
INFACT hat geschrieben:T'schuldigung ich kann nicht so richtig erklären:cry: :wink: :wink:
Daran solltest Du arbeiten! (Das meine ich ernst!)

Code: Alles auswählen

>>> turn("abc","a")
'\xc2\xc3\xc4'
eigentlich sollte da jetzt bcd stehen... :?:
Nein! Du verschiebst ja nicht um "1", sondern um 97! Und 97+97 ist eben nicht 98 ;-)

Denk mal drüber nach!

Zeile 5 und 6 machen etwas falsches. Setze Dich mal mit dem Modulo-Operator auseinander. yipyip benutzt den z.B. ja auch in seinem Code.

Verfasst: Freitag 20. März 2009, 18:01
von INFACT
Ok ich habe es jetzt geschafft:

Code: Alles auswählen

def rotate(seq, n):
    
    m = n % len(seq)
    return seq[m:] + seq[:m]

def turn(seq, i):
	end=""
	for j in seq:
		code=(ord(j)+ord(i))
		if code>255:
			code-=255
		end=end+chr(code)
	return end

def ccaesar(seq, i):
    ch=""
    for j in seq:
        end=turn(j, i)
        end=rotate(end, ord(i))
        ch=ch+str(end)
    return ch

def encodepw(pwd):
    i=""
    for j in pwd:
        jep=ord(j)
        jep=255-jep
        i=i+str(chr(jep))
    return i

def codecaesar(seq, i):
    """Codes the text seq with the password i"""
    ch=seq
    for j in i:
        ch=ccaesar(ch,j)
    return ch
    
def encodecaesar(seq, i):
    """Encodes the text seq with the password i"""
    i=encodepw(i)
    ch=seq
    for j in i:
        ch=ccaesar(ch,j)
    return ch
Hier noch ein beispiel:

Code: Alles auswählen

>>> codecaesar("abcd","password")
'\xd7\xd8\xd9\xda'
>>> encodecaesar('\xd7\xd8\xd9\xda',"password")
'abcd'

Verfasst: Freitag 20. März 2009, 18:06
von Hyperion
yipyip hat geschrieben:Du suchst wohl einfach nur das hier:

Code: Alles auswählen

def rotate(seq, n):
  
  m = n % len(seq)
  return seq[m:] + seq[:m]


print rotate('abcd', -1)
ls = [rotate('abcdefg', i) for i in range(9)]
for i in ls:
  print i
:wink:
yipyip
Und hier mit einer itertools Lösung:

Code: Alles auswählen

from itertools import islice, chain

def shift(iterable, offset=1):
    offset = offset % len(iterable)
    return chain(islice(iterable, offset, None), islice(iterable, offset))
Bin mal auf andere (optimiertere) Varianten gespannt :-D

Verfasst: Freitag 20. März 2009, 18:19
von Hyperion
ok, mal einige Kommentare im Quellcode:
INFACT hat geschrieben:Ok ich habe es jetzt geschafft:

Code: Alles auswählen

def turn(seq, i):
	end=""
	for j in seq:
		code=(ord(j)+ord(i))
#
# das folgende ist immer noch falsch
#
		if code>255:
			code-=255
		end=end+chr(code)
	return end

def encodepw(pwd):
    i=""
    for j in pwd:
        jep=ord(j)
# das sieht mir auch falsch aus!
        jep=255-jep
        i=i+str(chr(jep))
    return i

# besser encode_caesar()
def codecaesar(seq, i):
    """Codes the text seq with the password i"""
    ch=seq
    for j in i:
        ch=ccaesar(ch,j)
    return ch
    
# Du meinst decode_caesar()
def encodecaesar(seq, i):
    """Encodes the text seq with the password i"""
    i=encodepw(i)
    ch=seq
    for j in i:
        ch=ccaesar(ch,j)
    return ch
Die Variablen sind teilweise wenig aussagekräftig! was ist ein "i"? Damit kann man wenig anfangen ;-)

Verfasst: Freitag 20. März 2009, 19:47
von yipyip
@Hyperion:
Nicht optimiert, aber eine Variante:

Code: Alles auswählen

In [159]: rot = lambda s, n: (lambda k: (2 * s)[n%k:n%k+k])(len(s))

In [160]: rot('abcdefg', 1)
Out[160]: 'bcdefga'

In [161]: rot('abcdefg', -1)
Out[161]: 'gabcdef'
:wink:
yipyip

Verfasst: Samstag 21. März 2009, 08:54
von Leonidas
Ist ``a`` um -1 verschoben nicht ``z``?

Verfasst: Samstag 21. März 2009, 11:54
von Hyperion
Leonidas hat geschrieben:Ist ``a`` um -1 verschoben nicht ``z``?
Jein - hier im Kontext ging es um das Verschieben von Zeichenketten, wie das Shiften in Assembler z.B..

Der OP hat ja beides in seiner "Verschlüsselung", also das shiften bezüglich eines Alphabets und das Shiften des Inputs in eine bestimmte Richtung.

Verfasst: Samstag 21. März 2009, 15:23
von INFACT
Hyperion hat geschrieben:ok, mal einige Kommentare im Quellcode:
INFACT hat geschrieben:

Code: Alles auswählen

def turn(seq, i):
	end=""
	for j in seq:
		code=(ord(j)+ord(i))
#
# das folgende ist immer noch falsch
#
		if code>255:
			code-=255
		end=end+chr(code)
	return end

def encodepw(pwd):
    i=""
    for j in pwd:
        jep=ord(j)
# das sieht mir auch falsch aus!
        jep=255-jep
        i=i+str(chr(jep))
    return i 
Ich verstehe nicht was daran falsch ist, bei mir geht das einwandfrei! :?:
MfG Robin