Seite 1 von 2

Kodierer

Verfasst: Sonntag 23. Januar 2011, 12:56
von Penguin6
Hallo

Ich habe ein kleinen Kodierer gemacht, er funktioniert wie folgt:

0 1 2 3 4 # immer plus "Position" in ASCII
H a l l o
H b n o s

P y t h o n
P z v k s s

Ich hoffe es ist verständlich.

Variante 1: http://paste.pocoo.org/show/325304/
Variante 2: http://paste.pocoo.org/show/325318/

1. Ich habe nichts kommentiert, es ist nicht soviel Code, würdet ihr trotzdem kommentieren?
2. Welche Variante ist besser, oder sind beide schlecht?
3. Wenn ich decode(" " * 300) eingebe kommt manchmal IndexError: string index out of range und manchmal nicht, wieso? Finde den Fehler nicht.

Re: Kodierer

Verfasst: Sonntag 23. Januar 2011, 13:26
von Hyperion
Also das kann man einfacher lösen:

Code: Alles auswählen

In [19]: data = "Hallo"

In [20]: "".join(imap(chr, (starmap(add, (izip(count(), imap(ord, data)))))))
Out[20]: 'Hbnos'

In [21]: data = "Python"

In [22]: "".join(imap(chr, (starmap(add, (izip(count(), imap(ord, data)))))))
Out[22]: 'Pzvkss'
;-)

Auch wenn man es nicht funktional implementiert, ist die ASCII-Tabelle obsolet. Mit ord() bekommst Du doch den ASCII-Wert und mitr chr() wieder das Zeichen.

Einzig bei einem "Überlauf" weiß ich nicht, wie meine Lösung reagiert. Da müßte man ggf. noch ein modulo einbauen.

Zu deinem Code:

Code: Alles auswählen

 for i in range(len(klartext)):
So etwas kann man idR vermeiden, indem man enumerate() benutzt. Damit hast Du einen Index und das Element der Liste.

Bei Deiner zweiten Lösung würde ich anstatt 2x eine neue Liste anzulegen eher mit reversed(iterable) arbeiten.

Ach so, man sollte wohl noch erwähnen, dass der Codierer nicht wirklich sicher ist ;-) Da bringt selbst eine Cäsar-Chiffre mehr, da man dort nicht den Hinweis mit den korrekten Anfangsbuchstaben hat.

Edit: Das count() besser nach hinten stellen, dann klappt das decodieren leichter mit dem gleichen Code:

Code: Alles auswählen

from operator import add, sub
from itertools import imap, izip, count, starmap

def encode(data):
    return _code(data, add)

def decode(data):
    return _code(data, sub)

def _code(data, method):
    return "".join(imap(chr, (starmap(method, (izip(imap(ord, data), count()))))))

Re: Kodierer

Verfasst: Sonntag 23. Januar 2011, 13:46
von derdon
Eine interessante Definition von ASCII hast du da :)

Also mal die Signatur von Hyperion beachten

Re: Kodierer

Verfasst: Sonntag 23. Januar 2011, 14:08
von Penguin6
Danke viel Mal's!!!

Habe itertools nicht gekannt, werde ich gleich anschauen, bin noch ein Anfänger :oops:

Re: Kodierer

Verfasst: Sonntag 23. Januar 2011, 16:09
von Hyperion
Penguin6 hat geschrieben: Habe itertools nicht gekannt, werde ich gleich anschauen, bin noch ein Anfänger :oops:
Hehe... naja, die itertools muss man sich auch erst mal erarbeiten ;-) Leonidas hatte dazu afair mal nette Folien gebastelt. Leider find ich die grad nicht im wiki...

Man kann das auch "herkömmlich" lösen:

Code: Alles auswählen

In [53]: res = []

In [54]: for index, char in enumerate(data):
   ....:     res.append(chr(ord(char) + index))
   ....:
   ....:

In [55]: "".join(res)
Out[55]: 'Pzvkss'

Re: Kodierer

Verfasst: Sonntag 23. Januar 2011, 16:19
von cofi
Und das jetzt nochmal als LC bzw GE:

Code: Alles auswählen

"".join(chr(ord(char) + index) for index, char in enumerate(data))

Re: Kodierer

Verfasst: Sonntag 23. Januar 2011, 16:23
von Hyperion
cofi hat geschrieben:Und das jetzt nochmal als LC bzw GE:

Code: Alles auswählen

"".join(chr(ord(char) + index) for index, char in enumerate(data))
Ich glaube jetzt haben wie alle unterschiedlichen Konzepte, oder? :D

Re: Kodierer

Verfasst: Sonntag 23. Januar 2011, 16:31
von cofi
Hyperion hat geschrieben:Ich glaube jetzt haben wie alle unterschiedlichen Konzepte, oder? :D
Das klingt nach einer Herausforderung :) Zumindest objekt-orientierung fehlt noch, evtl mit Leonidas' Ring-Klasse, die irgendwo im Forum rumgeistert.

Und dann bleiben ja immernoch verschiedene Sprachen :)

Re: Kodierer

Verfasst: Sonntag 23. Januar 2011, 18:28
von derdon
cofi hat geschrieben:Und dann bleiben ja immernoch verschiedene Sprachen :)
Dann fang ich mal mit OCaml an. Imperativ, weil ich sehr lange nichts mehr damit gemacht habe: http://paste.pocoo.org/show/325480/

Re: Kodierer

Verfasst: Sonntag 23. Januar 2011, 18:58
von OverNord
Und hier ist eine mögliche Lösung in Erlang: http://paste.pocoo.org/show/325495/

Ich gebe zu, man könnte das ganze noch auf Nebenläufigkeit optimieren. Und es würde so auch noch nicht wirklich gut auf mehreren Erlang-Nodes laufen.

Re: Kodierer

Verfasst: Sonntag 23. Januar 2011, 19:17
von name

Re: Kodierer

Verfasst: Sonntag 23. Januar 2011, 19:22
von lunar
Haskell

Edit: So oder ähnlich könnte man das bestimmt auch in OCaml oder Standard ML lösen, allerdings wohl weniger elegant, da Zeichenkette in beiden Sprachen keine Liste von Zeichen sind, und erst explizit in eine solche konvertiert werden müssen. In OCaml wüsste ich auf Anhieb nicht einmal, wie das gehen könnte. Haskell ist eben doch die schönste funktionale Sprache ;)

Re: Kodierer

Verfasst: Sonntag 23. Januar 2011, 19:28
von name

Re: Kodierer

Verfasst: Sonntag 23. Januar 2011, 19:57
von Hyperion
Simples Java, weil 's so bloated ist :-) (Jaja, ist kein Enterprise Java :-D )

Re: Kodierer

Verfasst: Sonntag 23. Januar 2011, 20:26
von name
Hyperion hat geschrieben:Simples Java, weil 's so bloated ist :-) (Jaja, ist kein Enterprise Java :-D )
Wieso machst du die Methoden nicht static und wieso zum Teufel der Konstruktor?

Re: Kodierer

Verfasst: Sonntag 23. Januar 2011, 20:28
von Hyperion
name hat geschrieben:
Hyperion hat geschrieben:Simples Java, weil 's so bloated ist :-) (Jaja, ist kein Enterprise Java :-D )
Wieso machst du die Methoden nicht static...
Gute Idee!
name hat geschrieben: und wieso zum Teufel der Konstruktor?
s.o. ;-)

Re: Kodierer

Verfasst: Montag 24. Januar 2011, 10:32
von BlackJack
CoffeeScript:

Code: Alles auswählen

add = (a, b) -> a + b
sub = (a, b) -> a - b
ord = (char) -> char.charCodeAt(0)

_code = (f, text) -> String.fromCharCode((f(ord(c), i) for c, i in text)...)

encode = (plaintext) -> _code add, plaintext
decode = (cyphertext) -> _code sub, cyphertext

Re: Kodierer

Verfasst: Montag 24. Januar 2011, 18:58
von Hyperion
Da sich Leonidas nicht rührt und mich das Problem irgend wie motiviert hat, hier mein Vorschlag in Scheme.

Bitte nicht hauen, ist quasi mein erstes Scheme-Programm. Kritik daher erwünscht :-)

Re: Kodierer

Verfasst: Montag 24. Januar 2011, 19:38
von BlackJack
@Hyperion: `add` und `sub` scheint mir ein wenig redundant zu sein. Scheme hat dafür schon Funktionen. Die heissen `+` und `-`. Das sind in Scheme ja ganz normale *Namen* und keine speziellen Operatoren oder so.

Re: Kodierer

Verfasst: Montag 24. Januar 2011, 19:46
von Hyperion
BlackJack hat geschrieben:@Hyperion: `add` und `sub` scheint mir ein wenig redundant zu sein. Scheme hat dafür schon Funktionen. Die heissen `+` und `-`. Das sind in Scheme ja ganz normale *Namen* und keine speziellen Operatoren oder so.
*patsch* danke, ist korrigiert.