# Verschlüsselung



## javafm (29. Jun 2010)

ich hab ein Problem mit einem Array und einer Forschleife? In meinem Programm will ich eine Geheimschrift umsetzen nach einem bestimmten Algorithmus. Der Algorithmus ist von Blaise de Vigenére und Tritemius. Im Algorithmus soll folgender Sachverhalt abgebildet werden. 

Das Schlüsselwort ist INF
Das Eingabewert ist   COD
die Geheimschrift ist   KAG

Der Algorithmus ist:

Wenn I im Alphabet A ist dann ist der Eingabewert Buchstabe C ==> 2 stellen weiter von A.
Nimmt man die 2 Stellen auf die Basis des Schlüsselwortes dann ist die Geheimschrift I ==> 2 Stellen weiter = K !!!!!

Bei der zweiten Stelle ist B = N daraus folgt die Verschiebeung B zu O ==>  13 Stellen (Index)
N + 13 Stellen(Index) nach rechts ist = A

Bei der 3 Stelle ist C = F . Von C zu D ist es 1 Stelle (Index)
F + 1 Stelle ist G

Mein Ansatz des Aufbaus des Algorithmuses ist:

1:  For Schleife durch Array des Alphabeths
     ==> Ermittlung des Index (Abstand des Eingabewertes zu A)
2: For Schleife durch Array des Alphabeths Startwert 
    ist 1 Buchstabe des Schlüsselwortes + Index wert der 1 For Schleife(Zähler)
    Ausgabe des Buchstaben der Ausgegeben wird.

Kann man das so machen????


----------



## SlaterB (29. Jun 2010)

> Wenn I im Alphabet A ist dann ist der Eingabewert Buchstabe C ==> 2 stellen weiter von A.

interessante Beschreibung, wie wärs dagegen mit
'das Schlüsselwort INF entspricht in Zahlen (Position im Alphabet) 5, 9, 4 (oder so),
daher werden die Buchstaben im Klartext um 5 bzw. 9 bzw. 4 Stellen verschoben'

da du ungefähr verstanden hast, worum es geht, und die immer nützlichen Schleifen einsetzt kann man sagen:
nur weiter so, wird schon schiefgehen

aus dem unverständlichen Satz 'ist 1 Buchstabe des Schlüsselwortes + Index wert der 1 For Schleife(Zähler)' 
kann man aber nicht beurteilen, ob da wirklich ein korrekter Java-Befehl rauskommt..


----------



## javafm (29. Jun 2010)

[Java]



import InOut.ConsoleInOut;
import InOut.Console;

public class Geheim1
{

    public static void main (String args[])
    {

        // Deklaration der Variable und Felder

        char [] codetext;        // Array für die Eingabe des zu verschlüüselnden Wortes
        char [] schluesselwort;  // Array für das Schlüsselwort
        char [] geheimtext;      // Array für das Geheimwort
        String [] abc = {"A","B","C","D","E","F","G","H","I","J",
                "K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
        int anzahl = 0;

                // Eingabe ob verschlüsselt oder entschlüsselt wird

                System.out.println("Typen Sie bitte (1) zum Textverschlüsseln oder (2) zum Textentschlüsseln ein");

                int wahl = Console.readInt();

                if (wahl == 1)  // Verschlüsseln

                {


                    System.out.println("Geben Sie bitte den Text zum Verschlüsseln an");

                    codetext = Console.readCharArray();

                    System.out.println("Geben Sie bitte das Schlüsselwort an");

                    schluesselwort = Console.readCharArray();

                    int test = codetext.length; // Ermittlung der Länge des Eingabewertes 
                                                //- wichtig für die Anzahl der Schleifendurchläufe


                    int test1 = schluesselwort.length;

            //System.out.println(codetext );
            //System.out.println(schluesselwort );
            //System.out.println(test );
            //System.out.println(test1 );


            for (int i = 0; i < test ; ) // 1. Schleife -- wird solange durchlaufen wie der Codetext 
                                         // ist zur Vschlüsselung

            {

                for (int j = 0 ; j == 25 // 2. Schleife -- Ausgehend von A wird mit 
                                           //einer Zählvariable gesucht der Buchstabe des Schlüsselwortes

                {

                    if (abc[j] == schluesselwort.length[0])   // Abfrage wenn der 1. Buchstabe des
                                                              // Schlüsselwortes == dem Buchstaben 
                                                              // des Feldes abc ist.                      


                    {

                        break;        // Ausstieg aus der zweiten Schleife Bedingung 
                                      // Buchstabe Array abc = Buchstabe Schlüsselwort

                    }

                    anzahl = anzahl + 1;  // Zählvariable wird um 1 je Durchlauf erhöht um 

                    j++;              // Zählvariable der zweiten Schleife hochsetzen

                }

                i++; // 1 Schleife Wert - Zählvariable erhöhen

                for (int t = 0 ; t < 25 ; t++ )  // Ausgabeschleife für die Geheimschrift

                {
                    if ( t == anzahl)  // Zähler ist erreicht 

                    {


                        System.out.print(abc.length[anzahl]);

                    }

                }

            }
        } 
        if (wahl == 2) // entschlüsseln
        {
        }
    }
}

[/Java]]

Ich hab da noch ein paar Schwierigkeiten. mit den Array Feldern Char und dem Index?
Hat jemand eine Idee???


----------



## SlaterB (29. Jun 2010)

hmm, ok, so führt das dann doch zu nix,

bleiben wir vorerst bei EINER Schleife:
in jedem Durchlauf den Schlüssel-Char bestimmen (1), davon die Position im Alphabet bestimmen (2),
den Klartext-Buchstaben bestimmen und je nach Schlüssel verändern (3)
usw.

kommst du damit voran, hast du bei einer der drei konkreten Aufgaben 1-3 Probleme?

-----

GANZ GANZ wichtig:
niemals bei einfachen Algorithmus-Aufgaben etwas von der Konsole einlesen,
schreibe zunächst 

char [] codetext = "AFWLFD".toCharArray();
oder ähnlich, dann musst du das nicht bei jedem Test alle 5 Min. neu eintippen mit Fehlermöglichkeit

wenn ganz am Ende alles funktioniert, dann gerne die Eingabe davor aktivieren


----------



## faetzminator (29. Jun 2010)

Ein KSKB wär etwas toller.
Ich weiss nicht genau, was du machen willst, aber mit SlaterB's Aussage und [c]- i[/c] dahinter komme ich auf das "korrekte" Ergebnis (von deinem ersten Post) 

```
String input = "COD";
String code = "INF";

StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
    sb.append((char) ('A' + (input.charAt(i) + code.charAt(i) - 2 * 'A' - i) % 26));
}
System.out.println(sb.toString());
```
Funktioniert so natürlich nur, wenn [c]input.length() == code.length()[/c].


----------



## javafm (29. Jun 2010)

Wenn der zu Kodierende Wert 

String input = "CODIERUNGSTHEORIE";
String code = "INFORMATIK";

größer ist als das Schlüsselwort?
Wie gehe ich damit um?


----------



## SlaterB (29. Jun 2010)

keine Vorstellung?
- du könntest die restlichen Buchstaben nicht verschlüsseln,
- du könntest die restlichen auch verschlüsseln und einen zufälligen Schlüssel verwenden, hmm, wer soll das entschlüsseln und wie?
- du könntest als Schlüssel für den restlichen input genau einen Char vom Codewort immer wieder verwenden, z.B. immer das I,
das macht dich übermäßig angreifbar gegen Dekodierung, was du nicht wissen kannst,

fällt dir noch mehr ein?


----------



## faetzminator (29. Jun 2010)

SlaterB will aber nicht etwa darauf raus, mit dem bereits verschlüsselten Block den nächsten Teil zu verschlüsseln  ?


----------



## javafm (29. Jun 2010)

Zur Verschlüsselung wird ein Schlüsselwort benötigt, das die Auswahl der 26 möglichen zyklischen Vertauschungen der alphabetischen Anordnung A, B, C, ... steuert.

Um im jeweils ausgewählten Alphabet das richtige Ersetzungssymbol zu finden, benutzt man den sogenannten St.-Cyr-Schieber (nach der gleichnamigen französischen Militärschule, die ihn um 1880 benutzte), dessen zwei Teile gegeneinander verschiebbar sind wie bei einem Rechenschieber (Abb. 1).



Abb. 1 






Beispiel

Soll der Text CODIERUNGSTHEORIE verschlüsselt werden und lautet das Schlüsselwort INFORMATIK, dann stellt man für jeden Buchstaben des Klartextes zusammengehörige Buchstabenpaare auf Index und Zunge untereinander.


Für den ersten Buchstaben des Klartextes (C) stellt man den ersten Buchstaben des Alphabets (A) auf dem Index über den ersten Buchstaben des Schlüsselworts (I) auf der Zunge ein (Abb. 2).


Abb. 2 




Dann sucht man auf dem Index den Klartextbuchstaben, auf der Zunge darunter steht dann der Codebuchstabe (K).

Für den nächsten Buchstaben sieht das dann wie in der Abb. 3 und der Abb. 4aus.


Abb. 3 





Abb. 4 





Auf diese Weise erhält man für den Klartext CODIERUNGSTHEORIE den Codetext KAGTRYOZGTRJXPUFO.


Ist der Klartext länger als das Schlüsselwort, dann wird das Schlüsselwort so oft hintereinander gelegt, wie der Klartext es fordert. Ebenso werden die 26 Buchstaben des Alphabets hintereinander gestellt.

Allgemein erhält man das Schema der Abb. 5.


Abb. 5 




i = laufende Nummer der Buchstabenfolge im Klartext. 
SCHLÜSSEL _, KLARTEXT  und CODETEXT  sei jeweils der Ordnungswert des i-ten Buchstabens des Schlüsselworts, des Klartextes und des Codetextes.

Es ergibt sich die Gleichung der Abb. 6.


Abb. 6 




Für das Entschlüsseln gilt die gleiche Anordnung. Zur Decodierung des 1. Codebuchstabens wird der 1. Buchstabe des Alphabets (A) auf dem Index über den ersten Buchstaben des Schlüsselwortes (I) auf der Zunge eingestellt. Dann sucht man auf der Zunge den Codetextbuchstaben, auf dem Index darüber steht der Klartextbuchstabe (C) usw.

Aufgabe:
Entwerfen Sie einen Algorithmus zum Verschlüsseln und Entschlüsseln von Texten nach der erläuterten Methode und realisieren Sie den Algorithmus als Java-Programm. Die Ausgabe soll folgende Form aufweisen:


Schlüsselwort:                                 
INFORMATIK
Text:                                           
CODIERUNGSTHEORIE             
Verschlüsselter Text:                     
KAGTRYOZGTRJXPUFO

Schlüsselwort:
INFORMATIK
Text:
KAGTRYOZGTRJXPUFO
Entschlüsselter Text:
CODIERUNGSTHEORIE

Das Programm soll wahlweise entschlüsseln oder verschlüsseln für beliebige Schlüsselworte. Entschlüsseln Sie mit Ihrem Programm folgenden Text (Schlüsselwort: INFORMATIK): 

LMVSNIYZSJCCUFUPOJHJQZXVGTEEGJLBRPNVYVZGUQRENGKGZESQMGXPAFKQFSMPFSUQWK



Ergänzende Bemerkungen
   Es stellt sich jetzt natürlich die Frage, ob man einen Codetext entschlüsseln kann, wenn man das Schlüsselwort nicht kennt. Bazaries hat um 1880 eine Methode erfunden, die auf der Vorraussetzung beruht, dass man ein Wort errät, das mit großer Wahrscheinlichkeit im Klartext enthalten ist. Die Idee dabei ist, dass die Beziehung zwischen Schlüsselwort und Klartext umkehrbar ist, d.h. das im Klartext vermutete Wort wird als Schlüsselwort benutzt und der Codetext als Codetext. Dann muss unter dem vermuteten Wort als Klartext bei der Entschlüsselung das wirkliche Schlüsselwort erscheinen, wenn auch evtl. in einer zyklischen Vertauschung der Buchstabenfolge. Da man nicht wissen kann, wo das vermutete Wort im Klartext steht muss die »richtige Stelle« durch systematisches Probieren gefunden werden, bis man das Schlüsselwort erkennt. Diese Methode versagt, wenn das Schlüsselwort eine willkürliche Buchstabenfolge ist. Eine Verallgemeinerung der hier dargestellten Methode liegt vor, wenn das Alphabet auf dem St.-Cyr-Schieber anders angeordnet ist (irrationales Alphabet). Außerdem kann man mit mehreren Alphabeten arbeiten oder das Schlüsselwort nach einer bestimmten Anzahl von Zeichen ändern. Dies ist das Grundprinzip der maschinellen Verschlüsselung.



DAs ist das Ziel der Aufgabe_


----------



## faetzminator (29. Jun 2010)

In dem Aufgabentext steht die Antwort auf deine Frage bereits.


----------



## javafm (29. Jun 2010)

Ja aber ich kann es noch nicht umsetzen?


----------



## SlaterB (29. Jun 2010)

wenn du ein Array der Länge 5 hast und Index 7, dann ist
7 % 5 der gesuchte Index 2 so als wenn man das Schlüsselwort mehrfach hintereinanderschreiben würde

beim Alphabet hilft % auch,
ansonsten eine while-Schleife, 
solange Index zu groß, ziehe Länge ab


----------



## javafm (29. Jun 2010)

Wie programmiert man so was in Java?


----------



## SlaterB (29. Jun 2010)

int k = 7 % 5;


----------



## javafm (30. Jun 2010)

Ich habe jetzt mein Programm aktualisiert 

[Java]

import InOut.ConsoleInOut;
import InOut.Console;

public class Geheim4
{
    public static void main (String args[])
    {

        System.out.println("Typen Sie bitte (1) zum Textverschlüsseln oder (2) zum Textentschlüsseln ein");

        int wahl = Console.readInt();

        if (wahl == 1)  // Verschlüsseln

        {

            String input = "CODIERUNGSTHEORIE";
            String code = "INFORMATIK";

            while (input.length() < code.length());     // Eingabewort ist größer als das 
            // Schlüüselwort
            {
                code = code + code; 
                System.out.println(code);
            }

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < input.length(); i++) {
                sb.append((char) ('A' + (input.charAt(i) + code.charAt(i) - 2 * 'A' - i) % 26));
            }
            System.out.println(sb.toString()); 
        }    

        if (wahl == 2)  // Entschlüsseln

        {
            String input = "KAGTRYOZGTRJXPUFO";
            String code = "INFORMATIK";

            while (input.length() < code.length());     // Eingabewort ist größer als das 
            // Schlüüselwort
            {
                code = code + code; 
                System.out.println(code);
            }

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < input.length(); i++) {
                sb.append((char) ('A' + (input.charAt(i) + code.charAt(i) - 2 * 'A' - i) % 26));
            }
            System.out.println(sb.toString()); 
        }    
    }
}

[/code]


Mein Problem ist, dass ich bei einem Eingabe des Wertes 

String input = "CODIERUNGSTHEORIE";
String code = "INFORMATIK";

Als Ergebnis den Begriff "KAGTRYOZGTRJ>PUF5" erhalte. Richtig wäre aber "KAGTRYOZGTRJXPUFO"


----------



## SlaterB (30. Jun 2010)

du rechnest -i rein, das kann ganz schön groß werden, z.B. beim vorletzen E

E + F - i = 4 + 5 - 12 = -3

-3 % 26 ist leider -3 in Java, du brauchst da 22, ein Wert zwischen 0 und 25

scheibe in der Klammer vor dem % 26 noch +26, notfalls gar + 10 * 26, dann ist sichergestellt dass du im postivien Bereich bist und am Ende etwas zwischen 0 und 25 rauskommt,

beim Dekodieren auch bedenken, aber da musst du eh noch etwas anders vorgehen

----

in diesem Fall würde es interessanterweise auch klappen, wenn du auf die - 2 * 'A' verzichtest, denn 'A' == 65, das doppelte davon sind 130, was wiederum genau 5x 26 entspricht, also nicht stört, denn Vielfache von 26 kannst du beliebig draufzählen solange am Ende % 26 steht,
der Ordnung halber sind die - 2* 'A' aber schon wichtig, lasse die und dann noch + 26


----------



## javafm (30. Jun 2010)

Wie kann ich entschlüsseln, den Algorithmus muß ich erst noch entwickeln? 
Kannst Du mir da mal Bitte Hilfe geben?


----------



## SlaterB (30. Jun 2010)

nicht wenn du nur den Satz 'bitte helfen' zusammenbringst und keinerlei eigene Ideen hast,
schau dir doch an wie die Verschlüsselung geht, welche Werte beteiligt sind und mit welchem mathematischen Operatoren man das zurückrechnen könnte

noch ein Tipp:
das ganze heißt Vigenere-Verschlüsselung, kann man auch bei google suchen..


----------



## javafm (30. Jun 2010)

HAst Du recht!

Wenn ich den Mathematischen Algorythmus vorwärts berechnen kann dann müßte ich die Formel ja drehen können. 

Beim Vorwärtsberechenen habe ich den Buchstaben A als Quelle
der hat den Mathematischen Wert 0. Dieser wird verschlüsselt mit dem Buchstaben E
was den Wert 5 hat. So ergibt sich als Verschlüsselter Buchstabe die Addition 
der beiden WERTE und das Wäre 5 = E, oder?

Bei der Rückwärtsberechnung wäre der WEG  aus der Quelle E mit dem Wert 5
wird das ZEichen der Verschlüsselung abgezogen E = 5. Das heißt das der Wert 
des Ausgebegene sein wird 5-5 = 0 wäre.  allso E - E = A

liege ich da richtig?


----------



## SlaterB (30. Jun 2010)

die Richtung ist gut, ja


----------



## javafm (30. Jun 2010)

```
for (int i = 0; i < input.length(); i++) {
                sb.append((char) ('Z' + (input.charAt(i) - code.charAt(i) - 2 * 'A' - i + 26 + 1) % 26) );
            }
            System.out.println(sb.toString()); 
        }
```


Ich hab jetzt folgendes Ergebnis :

Typen Sie bitte (1) zum Textverschlüsseln oder (2) zum Textentschlüsseln ein
2
Bitte Geben Sie den zu Entschlüsselnden Begriff ein: 
KAG
Bitte Geben Sie den Schlüsselbegriff ein: 
INF
CMZ

Er bringt CMZ anstatt COD  

Auffallend beim 1 Buchstaben funktioniert der Algorithmus 
Beim 2 Buchstaben ist der Abstand M zu O 2 beim 3 Buchstaben ist der Abstand Z zu D 4 ???????????


----------



## SlaterB (1. Jul 2010)

beim Verschlüsselt rechnest du + Code - i und jetzt - Code - i,

auf + i kommst du nicht, nichtmal durch pures Ausprobieren?

das 'Z' und + 1 ist bisschen merkwürdig, 'A' würde unter gewissen Umständen reichen da praktisch wie zuvor Buchstaben verschoben werden,
das + - usw, sollte alles im % 26-Block abgehandelt werden,

- 2 * 'A' ist schlecht, klappt nur da wie früher geschrieben der ganze Abschnitt im Grunde wegfällt,
hier würdest du den Code abziehen, also einmal -'A' und einmal +'A', was sich gar aufhebt,

sb.append((char)('A' + (input.charAt(i) - code.charAt(i) - 'A' + 'A' + i + 26) % 26));
wäre etwas konformer, oder gekürzt
sb.append((char)('A' + (input.charAt(i) - code.charAt(i) + i ) % 26));


----------



## Spewer (21. Sep 2012)

Auch wenn es schon über 2 Jahre alt ist, ich musste die Aufgabe auch machen und für alle, die sich dafür interessieren ist hier der fertige Quellcode, der soweit alles enthält was wichtig ist.

[WR]Es handelt sich um eine Lösung:[/WR]

```
import inout.Console;

public class Verschluesselung
{
  static void linieAusgeben()
  {
    System.out.println("------------------------------------");
  }

  public static void textVerschluesseln(String originalText, String schluesselwort)
  {
    originalText = originalText.toUpperCase();
    schluesselwort = schluesselwort.toUpperCase();
    
    while (schluesselwort.length() < originalText.length())
    {
      schluesselwort += schluesselwort;     
    }   

    StringBuilder verschluesselterText = new StringBuilder();

    for (int i = 0; i < originalText.length(); i++)
    {
      verschluesselterText.append((char) ('A' + (originalText.charAt(i) + schluesselwort.charAt(i) - i) % 26));
    }
    System.out.println(verschluesselterText.toString());

  }

  public static void textEntschluesseln(String verschluesselterText, String schluesselwort)
  {
    verschluesselterText = verschluesselterText.toUpperCase();
    schluesselwort = schluesselwort.toUpperCase();

    while (schluesselwort.length() < verschluesselterText.length())
    {
      schluesselwort += schluesselwort;
    }
    
    StringBuilder originalText = new StringBuilder();

    for (int i = 0; i < verschluesselterText.length(); i++)
    {
      originalText.append((char) ('A' + (verschluesselterText.charAt(i) - schluesselwort.charAt(i)  + i + 26 ) % 26) );
    }
    System.out.println(originalText.toString());

  }

  public static void main(String args[])
  {
    int run = 0;
    char auswahl;
    String originalText;
    String schluesselwort;
    String verschluesselterText;

    while (run == 0)
    {
      linieAusgeben();
      System.out.println("Bitte Funktion auswählen: \n");
      System.out.println("1: Text verschlüsseln");
      System.out.println("2: Text entschlüsseln");
      System.out.println("0: Abbruch");
      linieAusgeben();

      auswahl = Console.readChar();

      switch (auswahl)
      {
        case '1':
          System.out.println("Bitte geben sie das zu verschlüsselnde Wort ein: ");
          originalText = Console.readString();
          System.out.println("Bitte geben Sie das zu verwendende Schlüsselwort ein: ");
          schluesselwort = Console.readString();
          System.out.println("");
          textVerschluesseln(originalText, schluesselwort);
          break;

        case '2':
          System.out.println("Bitte geben sie das zu entschlüsselnde Wort ein: ");
          verschluesselterText = Console.readString();
          System.out.println("Bitte geben Sie das zu verwendende Schlüsselwort ein: ");
          schluesselwort = Console.readString();
          System.out.println("");
          textEntschluesseln(verschluesselterText, schluesselwort);
          break;

        case '0':
          run = 1;
          break;

        default:
          System.out.println("Fehlerhafte Eingabe: " + "Bitte nur 1, 2 oder 0 eingeben");
          continue;
      }
    }

    System.out.println("Das Programm wurde beendet.");
  }
}
```

Das Thema kann bestimmt auch geschlossen werden.


----------

