www.jammni.de

Logo - Kleiner Drache
Login
Username:

Passwort:

Daten merken
Auto-Login
Registrieren
 
Online
niemand
 
Forumsuche
Suche nach:

Logo - DracheHaskell-Forum

Locust

Gepostet:
21.01.2006 17:54

Würfel-Chiffrierung  
Habe da folgende Aufgabe:

Vertraulichkeit von Nachrichten versucht man schon seit der Antike durch geeignete Verschlüsselung der Nachrichten sicherzustellen. Eine einfach zu berechnende (und auch einfach zu brechende!) Methode ist eine als Würfel-Chiffrierung bekannte Verschlüusselungstechnik. Bei der Würfel-Chiffrierung wird eine Zeilenlänge k > 1 als Kennzahl vereinbart. Die Chiffrierung einer Nachricht geschieht dann in folgender Weise. Die zu codierende Nachricht wird zunächst in Zeilen der Länge k aufgeschrieben, wobei die letzte Zeile ggf. unvollständig bleibt. Die codierte Nachricht erhält man dann durch spaltenweises Auslesen der Zeilen. Folgendes Beispiel illustriert das Vorgehen. Die Nachricht algorithmenunddatenstrukturen liefert bei Kennzahl 7 über den Zwischenschritt

algorit
hmenund
datenst
rukture
n

die Codierung ahdrnlmaugetkonetrunuinsrtdte. Schreiben Sie zwei HASKELL-Funktionen codeCube :: String -> Int -> String und decodeCube :: String -> Int -> String zur Codierung bzw. Dekodierung von Zeichenketten nach der Würfelmethode. Für die Funktion codeCube gibt das ganzzahlige Argument die für die Chiffrierung zu verwendende Kennzahl an, für die Funktion decodeCube die Kennzahl, die bei der Chiffrierung verwendet worden ist.


Hinweis: Für die Lösung dieser Aufgabe kann der Operator !! hilfreich sein, mit dem man direkt auf ein Listenelement zugreifen kann. Die Nummerierung beginnt dabei mit 0. Z.B.: "daten"!!0 => ’d’, oder [5,4,3,2]!!3 => 2.

Könnt ihr mir helfen, habe nicht so viel Ahnung von Haskell dashalb wären Hilfestellungen oder Ansätze gut.

schon mal danke im voraus
Zum Seitenanfang    
 
Jacke

Gepostet:
21.01.2006 23:59

   
einstring ="algorithmenunddatenstrukturen"

--zunächst hab ich den string zerlegt
--zahl ist dieausgemachte zahl k
zerlege [] zahl [] accliste=accliste
zerlege [] zahl acc accliste=accliste++[acc]
zerlege (l:ls) zahl acc accliste
|(zahl==length acc) = zerlege (l:ls) zahl [] (accliste++[acc])
|otherwise = zerlege ls zahl (acc++[l]) accliste

use:
c:\zerlege einstring 7 [] []
["algorit","hmenund","datenst","rukture","n"]
c:\

ich programmier morgen früh weiter ...:-)

gruß jacke
Zum Seitenanfang    
 
Jacke

Gepostet:
22.01.2006 11:42

   
so hier ist die CodeCube-Funktion:




--zunächst hab ich den string zerlegt
--zahl ist dieausgemachte zahl k
zerlege [] zahl [] accliste=accliste
zerlege [] zahl acc accliste=accliste++[acc]
zerlege (l:ls) zahl acc accliste
|(zahl==length acc) = zerlege (l:ls) zahl [] (accliste++[acc])
|otherwise = zerlege ls zahl (acc++[l]) accliste

--so und jetzt die eigentliche funktion
--mit help wird immer eine spalte mithilfe des index ausgelesen
--die list comprehension ruft nun help mit jeden index von null bis länge der zerlegten liste auf
--die fall unterscheidung bei help ist nötig weil die letzte liste (der zerlegten liste) nicht vollständig sein muss
--sie könnte zum beispiel nur ein element enthalten
codeCube liste zahl =concat[(help (zerlege liste zahl [] []) x [])|x<-[0..(length(zerlege liste zahl [] [])+1)]]
where help [] z acc=acc
help (l:ls) z acc
| (length l>z) = help ls z (acc++[l!!z])
| otherwise = help ls z acc


verwendung:
c:\codeCube einstring 7
"ahdrnlmaugetkonetrunuinsrtdte"

falls du dich mit list comprehension noch nicht so auskennst ich werde in den nächsten tagen vllt auch heute noch ein kapitel im haskell tutorial dazu schreiben
so morgen programmier ich dann die decode funktion..Smilie
Zum Seitenanfang    
 
Locust

Gepostet:
23.01.2006 18:53

   
Vielen dank Jacke. Hat mir echt weitergeholfen.

Wollte nur noch wissen was [] die klammern und das acc bedeuten.

zerlege [] zahl [] accliste=accliste
zerlege [] zahl acc accliste=accliste++[acc]
Zum Seitenanfang    
 
Jacke

Gepostet:
23.01.2006 19:11

   
zerlege funktion:
also [] ist eine leere liste...bei rekursion ist es so, dass man einen rekursionsanker angibt...der anker ist in diesem fall die leere liste
man nimmt ja immer ein element mehr aus der liste raus bis eben kein element mehr drin ist..

acc ist der accumulator...an sich einfach nur ne normale variable, in die ich zwischenergebnisse reinspeicher...in der zerlege-funktion hab ich in acc immer das listenstückchen drin, welches ich gerade abtrennen will...
und ich packe in acc solange elemente rein bis zahl-stück drin sind...
zahl gibt dabei die größe der teillisten an...

in accliste ist dann die finale liste drin...in der alle kleinen teilisten enthalten sind...


zerlege [] zahl [] accliste=accliste
hier wird die accliste zurrückgeben wenn die kleine teiliste also der accumulator leer ist

zerlege [] zahl acc accliste=accliste++[acc]
sollte noch etwas in acc drin sein dann gebe ich die vereinigung der beiden listen zurrück
Zum Seitenanfang    
 
Jacke

Gepostet:
24.01.2006 15:14

   
so und nun die decodefunktion ist vllt etwas umständlich, aber es geht :D:


--zerlegt einen kodierten string in blöcke
--use:
--zerlege2 str 7 [] 0 [] 1 4
--["ahdrn","lmau","getk","onet","runu","insr","tdte"]

zerlege2 [] zahl acc acc2 accliste rest rund=accliste++[acc]
zerlege2 (l:liste) zahl acc acc2 accliste rest rund
|(rest==acc2) &&((länge acc) < rund) =zerlege2 liste zahl (acc++[l]) acc2 accliste rest rund
|(rest==acc2)&&((länge acc)== rund) =zerlege2 (l:liste) zahl [] acc2 (accliste++[acc]) rest rund
|(rest > acc2)&& ((länge acc)==rund) =zerlege2 liste zahl (acc++[l]) (acc2+1) (accliste) rest rund
|(rest > acc2)&& ((länge acc)<rund) =zerlege2 liste zahl (acc++[l]) acc2 accliste rest rund
|otherwise = zerlege2 (l:liste) zahl [] acc2 (accliste++[acc]) rest rund





--zelegt eine matrix spaltenweise
spalte [] = []
spalte [v] = map toList v
where toList :: a -> [a]
toList x = [x]
spalte (v:vs) = zipWith ( : ) v (spalte vs)


---dekodiert den string und ruft dabei die funktionen zerlege2 und spalte ...concat macht dann einen string daraus...
--use:
--c:\decodeCube str 7
--"algorithmenunddatenstrukture"



decodeCube lis zahl= concat(spalte (zerlege2 lis zahl [] 0 [] (rest) (rund)))
where
rund=(länge (lis) ) `div` zahl
rest= mod (länge lis) zahl


--rund ist abgerundet wieviel volle 7ner spalten es gibt in diesem fall 4
--rest sagt wieviel elemente im letzten zerlegten stückchen sind
--in acc wird das listenstückchen was grade zusammengestellt wird gespeichert
--in acc2 wird gespeichert wieviel volle spalten schon erstellt wurden acc2 wird mit 0 initialiesiert
--acc liste enthält dann die liste die zurrückgegeben wird...wird mit [] initialisiert
--bestimmt die länge einer liste
länge []=0
länge (l:ls)=1+ länge ls

Zum Seitenanfang    
 
Locust

Gepostet:
24.01.2006 17:45

   
Nochmals danke Jacke. Die Erläuterungen sind ziemlich gut. Habe es jetzt auch verstanden.
Zum Seitenanfang    
 
Jacke

Gepostet:
24.01.2006 18:54

   
edit ich hab nochmal was am quelltext für die decode-funktion abgeändert...
jetzt geht er wenigstens
gruß jacke
Zum Seitenanfang