# String mit Hilfe von Array verschlüsseln



## schrobi (6. Jun 2009)

Hallo Leute,

habe eine Aufgabe an der ich nun schon seit heut morgen sitz aber irgendwie finde ich mal wieder keinen Anfang.

Bevor ich die ganze Aufgabe hier poste versuch ich mal mit Teilschritten und Eurer Hilfe weiter zu kommen.

Folgende Situation:
Der Schlüsel der Verschlüsselung soll ein 2D-Array sein (in diesem Fall [7][4]).
Nun soll ein Text eingegeben werden (also ein String) und in Form von diesem Array ausgegeben werden.
Hier mal das Beispiel:


> Klartext:
> Loesung Einsendeaufgabe 16‐02!
> Kodierung:
> L o e s
> ...



So kann man sehen wie es gemeint ist, denke ich.

Also mein Problem ist folgendes:
Ich lasse den Text eingeben aber weiss nicht wie ich ihn nun so in das Array packe dass er so Aussieht wie bei "Kodierung".

Hat da jemand einen Tipp wie ich da herangehen könnte?

Vielen Dank schonmal

Schrobi


----------



## Lexi (6. Jun 2009)

Könntest du den eingegebenen Text nicht einfach von String in ein char Array umwandeln ? Dann hast du einen char Array mit length = 28. Den kannst du dann mit einer for Schleife in ein 2D Array zerstückeln.


----------



## Marco13 (6. Jun 2009)

Man kann auch mit string.charAt(index) direkt die chars in einen 2D-Array schreiben. Prinzipiell muss man aber nichtmal das: Genaugenommen ist das nur ein bißchen Index-Gewurschtel:

```
String newString = "";
for (int i=0; i<string.length(); i++) newString += getChar(string, index);
```
wenn man die index-Berechnung in der "magischen Funktion" getChar richtig implementiert hat...


----------



## schrobi (6. Jun 2009)

Hm,

ich glaube dann ist das ein Problem mit dem decodieren.. ich poste doch mal die ganze Aufgabenstellung.



> Lernziel:
>  Zeichen aus Strings auslesen und in zweidimensionalen Reihungen positionieren.
> Programmieren sie ein Verschlüsselungsverfahren zur Kodierung von Texten. Sender und Empfänger
> vereinbaren einen Schlüssel der geheim bleiben soll und nicht mit übertragen wird. Dieser Schlüssel
> ...



Tadaa... Momentan steh ich wieder davor wie der Ochs vorm Berg:autsch:

Schrobi


----------



## Marco13 (6. Jun 2009)

Eigentlich müßte beim DEcodieren auch alles mit "Index-Magic" machbar sein, wenn mich nicht alles täuscht. Hast du Lexis Vorschlag mal ausprobiert?


----------



## schrobi (6. Jun 2009)

Mal ne doofe Frage: Was ist Index-Magic? Hab in unserem Script nichts davon gelesen..:bahnhof:

EDIT:
Habe eben folgenden Code bekommen und werde mich da jetzt mal reinlesen


```
// methoden importieren wegen tastatureingabe und dem zufallszahlgenerator
 
import java.io.*;
import java.util.Random;
import java.lang.String; 

class CodierungTest {
public static void main(String[] args) {
 
// n paar variable initialisieren
 
char[][] ciphertext = new char[7][4];
int temp = 0;
int tempFill = 0;
int alphaLength = 26;
int count = 0;
String codedText = "";
 
// den zu verschlüsselnden text annehmen und die leerzeichen entfernen
 
String plaintext = readString("Bitte den zu verschluesselnden Text eingeben: ");
plaintext = plaintext.replaceAll(" ", "");

 
// berechnen wieviel zeichen aufgefüllt werden müssen
// für texte ohne längen beschränkung müsste man hier das array aufstellen
// so das alle zeichen hinein passen
 
temp = 28 - plaintext.length();
if(temp < 0) {
System.out.println("Der Text darf max 28 Zeichen (ohne Leer) besitzen, in der jetztigen Version des Programmes.");
System.exit(1);
} else if(temp > 0) {
Random rNumber = new Random();
for(int i = 0; i < temp; i++) {
tempFill = 65 + rNumber.nextInt(alphaLength);
plaintext = plaintext + (char)tempFill;
}
}
 
// nun den text verschlüsseln
 
for(int j = 0; j < 7; j++) {
// zeilen
 
for(int n = 0; n < 4; n++) {
// spalten
 
ciphertext[j][n] = plaintext.charAt(count);
count++;
}
}
 
// den text aus dem array nehmen und in nen string schreiben
 
for(int m = 0; m < 4; m++) {
// spalten
 
for(int o = 0; o < 7; o++) {
//zeilen
 
codedText += ciphertext[o][m];
}
}
System.out.println(codedText);
}
 
// hilfsmethode für die tastatureingabe
 
static public String readString(String msg) {
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
while(true) {
System.out.print(msg);
try {
String eingabe = input.readLine();
return eingabe;
}
catch (Exception Fehler) {
{}
}
}
}
}
```


----------



## Spacerat (6. Jun 2009)

Ich weis nicht, ob es dem TO oder sonst jemandem aufgefallen ist, geschweige denn, ob sich jemand auf Anhieb vorstellen kann, was mit 2D-Reihung gemeint ist.
	
	
	
	





```
Loes
ungE
inse
ndea
ufga
be16
‐02!
```
Liest man jede Spalte von oben nach unten ergibt sich folgendes:
	
	
	
	





```
Luinub‐
onndfe0
egseg12
sEeaa6!
```
Und siehe da, aneinander gereiht ergibt sich ganz ohne irgend eine weitere Kodierung (z.B. "random()") der Schlüsseltext.
Es geht also darum, den Klartext in 7 Zeilen â 4 Zeichen zu zerlegen und anschliessend den Schlüsseltext spaltenweise daraus zusammenzufügen. Und das geht halt über den Index der jeweiligen Buchstaben im Klar- bzw. Schlüsseltext (symetrischer Code).
@Edit:  ...ist in diesem Fall natürlich ein asymetrischer Code, weil beim decodieren gespiegelt (4, 7) -> (7, 4).


----------



## hdi (6. Jun 2009)

du kannst mit einer for-schleife zeichenweise über einen string gehen:


```
char[] asCharArray = myString.toCharArray();
for(int i = 0; i<asCharArray.length; i++){
  // asCharArray[i] enthält jetzt den (i+1)-ten Buchstaben des Strings.
  // Je nachdem was i für einen Wert hat weisst du, wohin dieser Buchstabe
  // in den Ziel-Array reinmuss.
}
```

edit: äh sry als ich den beitrag angeklickt hab sah es so aus als gäbe es
noch keine antworten ?!


----------



## Marco13 (6. Jun 2009)

BTW: Mit "Index-Magic" meinte ich, dass du das nicht unbedingt ECHT in einen 2D-Array kopieren und da dann ("verschlüsselt") wieder rauslesen musst, sondern dass du, wenn du die Indizes bei Zugriffen wie eingabeString.charAt(*index*) geschickt berechnest, den verschlüsselten String auch zusammenbauen kannst, ohne einen 2D-Array zu erstellen.


----------



## schrobi (7. Jun 2009)

Erstmal Danke an Euch alle, dass ihr mir helfen wollt, find das Forum echt super :toll:

@Spacerat: 
Mir ist schon beim ersten lesen der Aufgabe aufgefallen dass der codierte Text nichts anderes ist, als der im Array gespeicherte, nur eben von oben nach unten und nicht von links nach rechts gelesen.
Mein Problem war/ist nur wie ich den Text welcher ja als String eingelesen wird, so in das Array bekommen dass die Buschstaben (bzw Zeichen) in der richtigen Reihenfolge gespeichert werden und dann in der -von-oben-nach-unten-Reihenfolge wieder ausgegeben werden. Bin mit Arrays noch ein wenig auf Kriegsfuß.

@Marco13:
So wie ich das verstehe habe ich mit Index-Magic dann KEIN Array oder? Dieses wird aber verlangt da ja sonst kein "Schlüssel" benutzt werden kann...(denk ich mal).

@hdi:
So wie ich das als "n00b" sehe ist es ungefähr das was ich brauche. Weiss nur noch nicht ganz wie ich das alles einbaue.

Hab hier mal meinen Code. Ist mir ein wenig peinlich das hier zu posten weil eigentlich noch kaum was drin steht. Ist der Ansatz mit dem Array denn wenigstens richtig?

Testklasse:

```
import java.io.*;


public class CodierungTester {

    public static void main(String[] args) {
        Codierung test = new Codierung();
        test.muh();
    }
}
```

Hauptklasse:

```
import java.io.*;


public class Codierung {
	
	//Eingabe des Users
	String input;
	//Integer zum Erfassen der laenge des Strings.
    int int01;
    //Array zum speichern der Eingabe.
    String[][] code = new String[7][4];
    
    /**
     *Methode zum einlesen der Usereingabe.
     */
    private void readIn() {
        BufferedReader br = new BufferedReader(
                    new InputStreamReader(System.in));
        try {            
            input = br.readLine();
        } catch (IOException e) {
        }
    }
    
    
    public final void muh() {
    	readIn();
    	
    	System.out.println("test " + input);
    	
    	
    }
}
```

So, zum Schluss muss ich mich noch entschuldigen, dass ich gestern nicht mehr geantwortet habe, aber da noch andere Module auf ihre Bearbeitung gewartet(schon fast geschrien) haben, musste ich da auch mal wieder ran. Programmieren frisst momentan echt meine Zeit auf, heut gibts nichts andres 

Freu mich auch Eure Antworten
Schrobi


----------



## Marco13 (7. Jun 2009)

schrobi hat gesagt.:


> @Marco13:
> So wie ich das verstehe habe ich mit Index-Magic dann KEIN Array oder? Dieses wird aber verlangt da ja sonst kein "Schlüssel" benutzt werden kann...(denk ich mal).


Doch - das sind dann nur parameter für die Indexberechnung. 

```
// For http://www.java-forum.org/java-basics-anfaenger-themen/83996-string-mit-hilfe-von-array-verschluesseln.html

class EncodeDecodeTest
{
    public static void main(String args[])
    {
        String s = "Loesung Einsendeaufgabe 16-02!";
        String es = encode(s, 4, 7);
        String ds = encode(es, 7, 4);

        System.out.println("Input  : "+s);
        System.out.println("Encoded: "+es);
        System.out.println("Decoded: "+ds);
    }

    private static String encode(String s, int x, int y)
    {
        s = s.replaceAll(" ", "");
        String t = "";
        for (int i=0; i<x*y; i++) t += getChar(s,(i%y)*x+(i/y));
        return t;
    }

    private static char getChar(String s, int i)
    {
        return (i>s.length())?'?':s.charAt(i);
    }
}
```
Aber mach' das mal mit dem Array, man muss davon ausgehen, dass die Übungsaufgabe gerade darauf _abzielt_, dass man lernt, mit Arrays umzugehen 

Zu deinem Programm: Es wäre vermutlich günstig, die Arraygrößen im Konsruktor zu übergeben - schließlich braucht man sie zum DEcodieren dann genau umgekehrt. 

```
public class Codierung 
{
....
    //Array zum speichern der Eingabe.
    String[][] code;

    public Codierung(int y, int x)
    {
        code = new String[y][x];
    }
   ...
}

// Erstellen eines Codierung-Objektes mit Schlüssel "7,4":
Codierung test = new Codierung(7,4);
```


----------



## Spacerat (7. Jun 2009)

schrobi hat gesagt.:


> Mir ist schon beim ersten lesen der Aufgabe aufgefallen dass der codierte Text nichts anderes ist, als der im Array gespeicherte, nur eben von oben nach unten und nicht von links nach rechts gelesen.


Ähm... hätt' mich auch gewundert, wenn nicht. Was mich nur verwirrt hat, ist die Tatsache, das hier beide Werte (Spalten und Zeilen) angegeben und damit die maximale Länge des Textes bestimmt werden. Normalerweise hat man nämlich nur eine, aus welcher sich die andere aufgrund der Textlänge ergibt ("zeilen = Math.ceil(textlaenge / spalten);").
"new String[7][4]" ist schon mal ein Ansatz. Besser wäre aber "new char[7][4]". Ich hab' hier mal ein Beispiel, welches die Klartextlänge nicht begrenzt.
	
	
	
	





```
public final class TextCoder
{
  private final int columns;

  public TextCoder(int columns)
  {
    this.columns = columns;
  }

  public String encrypt(String klartext)
  {
    klartext = klartext.replaceAll(" ", "");
    int textlength = klartext.length();
    if(klartext.length() % columns != 0) {
      textlength += (columns - (klartext.length() % columns));
    }
    int lines = textlength / columns;
    int index;
    StringBuffer rc = new StringBuffer();
    char[][] code = new char[columns][lines];
    for(int c = 0; c < columns; c++) {
      for(int el = 0; el < lines; el++) {
        index = el * columns + c;
        if(index < klartext.length()) {
          code[c][el] = klartext.charAt(index);
        } else {
          code[c][el] = (char) (128.0 * Math.random());
        }
      }
      rc.append(code[c]);
    }
    return rc.toString();
  }

  public String decrypt(String encrypted)
  {
    if(encrypted.length() % columns != 0) {
      throw new IllegalArgumentException("Text not encrypted using this TextCoder");
    }
    int lines = encrypted.length() / columns;
    StringBuffer rc = new StringBuffer();
    char[][] code = new char[lines][columns];
    for(int el = 0; el < lines; el++) {
      for(int c = 0; c < columns; c++) {
        code[el][c] = encrypted.charAt(c * lines + el);
      }
      rc.append(code[el]);
    }
    return rc.toString();
  }

  public static void main(String[] args)
  {
    TextCoder t = new TextCoder(4);
    String klartext = "Loesung Einsendeaufgabe 16-02!";
    String encrypted = t.encrypt(klartext);
    String decrypted = t.decrypt(encrypted);
    System.out.println("Klartext : " + klartext);
    System.out.println("Kodiert  : " + encrypted);
    System.out.println("Dekodiert: " + decrypted);
  }
}
```
@Edit: Ach ja... Hier noch die Ausgabe:
	
	
	
	





```
Klartext : Loesung Einsendeaufgabe 16-02!
Kodiert  : Luinub-onndfe0egseg12sEeaa6!
Dekodiert: LoesungEinsendeaufgabe16-02!
```


----------



## schrobi (7. Jun 2009)

Ohman. Ihr seid ja verrückt, dass Ihr das einfach so ausm Handgelenk schütteln könnt. Mich kostet sowas Jahre meines Lebens ...

Das sieht irgendwie schon fast zuu professionell aus Spacerat. Versteh mich nicht falsch. Ich will/werde das nicht einfacht mit copy-paste übernehmen und dann abgeben. Aber bisher war es immer so, dass die Musterlösung am Ende soooo einfach war und alle Studis viel zu kompliziert gedacht haben. 

Kennt einer von Euch evtl ne gute Seite wo explizit erklärt wird wie man einen String in ein Array packt. Oder könnt Ihr mir das mit einfachen Worten erklären?

Schrobi


----------



## faetzminator (7. Jun 2009)

```
byte[] stringInByteArray = someString.getBytes();
```
oder

```
char[] stringInCharArray = new char[someString.length];
someString.getChars(0, someString.length - 1, stringInCharArray, 0);
```


----------



## schrobi (7. Jun 2009)

Danke, werd mich da mal "reinwurschteln".
Kann ich das mit 2D-Arrays genau so lösen?


----------



## schrobi (6. Jun 2010)

Heeey, fast ein Jahr nich in dem Thread gewesen 

Moin Leute. 
Ja ich muss diesen Aufgabe leider noch einmal ausbuddeln.
Es geht um folgendes: Die Aufgabestellung hat sich geringfügig verändert und damit habe ich so meine Problemchen. Soweit nix neues 

Also das Programm wurde erweitert und die Verschlüsselung des Textes soll diesmal mittels zwei Methoden gelöst werden welche die "codierung" mittels Reihen und Spalten gleich mitbekommen. 
Wie gesagt, es ist nur ein Teil des Programms, der Rest läuft schon. Daher hier mal der Ausschnitt um den es geht:

```
public void encode(int rows, int cols) {
		
		code = new char[rows][cols];//[7][4]
		getText();
		int cleartext = text.length();
		int index;
		//StringBuffer rc = new StringBuffer();

		for(int c = 0; c < cols; c++) { //4mal
			System.out.println("test");
			for(int r = 0; r < rows; r++) { //7mal
		        index = r * cols + c;
		        if(index < text.length()) {
		          code[c][r] = text.charAt(index);
		          System.out.println("test2");
		        } //else {
		          //code[c][el] = (char) (128.0 * Math.random());
		    	//System.out.println("test3");
		    	//}
			}
			//rc.append(code[c]);
		}
		//rc.toString();
	}
```
Sieht noch ein wenig wirr aus, da in der Testphase. Spacerat dürfte der Code bekannt vorkommen 
Also der Text wird mittels getText() in die Methode geholt. In der Testklasse habe ich noch das hier: 
	
	
	
	





```
th.encode(7, 4);
```
Da Sieht man den gegeben Schlüssel. Also nun soll der Text mit Hilfe einer Matrix codiert werden. Und in einer ähnlichen Methode auch mit einer Matrix decodiert. 
Wenn ich nun aber meinen Text in der Eingabeaufforderung eingeb bekomme ich ab 17 Zeichen ein ArrayIndexOutOfBoundsException: 4 für diese Codezeile: 
	
	
	
	





```
code[c][r] = text.charAt(index);
```
.
Kann es sein dass zuerst die zweite for-schleife (die mit den rows) abgearbeitet wird?
Bekomme als Ausgabe bei 16 Zeichen dann nämlich:
test
test2
test2
test2
test2
und das ganze 4 mal. EDIT: hm. war doch richtig. Vohin war das aber anders???:L

Bin verwirrt. Bin über jegliche Tipps dankbar.

schrobi


----------



## schrobi (6. Jun 2010)

UPDATE:

Hier mein weiter veränderter Code:
	
	
	
	





```
public void encode(int rows, int cols) {
		code = new char[rows][cols];//[7][4]
		getText();
		int cleartext = text.length();
		int index;

		for(int r = 0; r < rows; r++) {
			for(int c = 0; c < cols; c++) {
		        index = r * cols + c;
		        if(index < text.length()) {
		          code[r][c] = text.charAt(index);
		        }
			}
		}
		for (int i = 0; i < cleartext; i++) {
		            for (int j = 0; j < code[i].length; j++) {
		                System.out.print(code[i][j]);
		            }
            System.out.println();
		}
	}
```
So weit so gut. Nun bekomme ich die Codierung richtig angezeigt, allerdings wirft er trotzdem wieder eine ArrayIndexOutOfBoundsException: 7 und zeigt diesmal auf 
	
	
	
	





```
System.out.print(code[i][j]);
```
 und in der TestKlasse auf 
	
	
	
	





```
th.encode(7, 4);
```
.

Warum?:bahnhof:

EDIT: Ach ich habs. Da muss natürlichg ein code.length und kein cleartext hin. Nu muss ich das nurnoch irgendwie wieder decodieren....uiuiui:rtfm:


----------



## Ebenius (6. Jun 2010)

Hast Du nun eine Frage? Oder hat sich grad alles erledigt?

Ebenius


----------



## schrobi (6. Jun 2010)

Also jetzt versuch ich grad die Decodierung hinzubekommen. Das codieren läuft. Werd mich bestimmt gleich nochmal melden, danke der Nachfrage


----------



## Akrim (5. Feb 2012)

Hey Leute.

Ich habe ein Problem. Und zwar soll ich ein Verschlüsselungsprogramm schreiben, sehr ähnlich zu dem in dem erste Post, das in einem Array gespeichert werden soll. Es gibt zwei Schlüssel und eine Nachricht, die der Benutzer selber eingeben soll. Die Nachricht soll dann in ein Array gespeichert werden und anschließend kodiert und ggb mit zufälligen Zeichen gefüllt. 
Es funktioniert soweit, dass man die Nachricht und die Schlüssel eingeben kann. Dann allerdings wird der Text in nur einer Spalte ausgegeben, obwohl das nicht so sein soll. Außerdem gibt er mir einen Fehler aus, wenn sich in der Nachricht Leerzeichen befinden.
Bisher haben mir die obrigen Posts leider nicht sehr geholfen.
Hier ist der Quellcode, ich hoffe, ihr könnt mir irgendwie weiterhelfen. 


```
import java.util.Random;
import java.util.Scanner;

public class Verschluesselung {
	
	private int zeilen;
	private int spalten;
	
	public Verschluesselung(int pZeilen, int pSpalten) { 
		
		zeilen = pZeilen;
		spalten = pSpalten;
		
	}
	
	private void codierteMatrixAusgeben(char[][] pCodierteMatrix) {

		System.out.println("Die codierte Matrix:");
		
		for (int i = 0; i < zeilen; i++)
		{
			for (int j = 0; j < spalten; j++)
			{
				System.out.print(pCodierteMatrix[i][j]);
			}
		}

	}
	
	private char[][] nachrichtInReihungSpeichern(String pNachricht) {
		
		char[][] text = new char[zeilen][spalten];
		int index = 0;
		if (pNachricht.length() < (zeilen * spalten)) {
			Random rnd = new Random();
			for (int i = pNachricht.length(); 
					i < (zeilen * spalten); 
					i++) {
				pNachricht += (char) (48 + rnd.nextInt(122-48));
			}
		}
		for (int i = 0; i < zeilen; i++) {
			for (int j = 0; j < spalten; j++) {
				text[i][j] = pNachricht.charAt(index);
				index++;
			}
		}
		return text;
	}
		
	
	
	public String verschluessleText(String pNachricht) throws IllegalArgumentException{
		
		
		if ((zeilen * spalten) < pNachricht.length())
			throw new IllegalArgumentException("Zu viele Zeichen. Bitte die Zeichen reduzieren.");
		
		char[][] text = nachrichtInReihungSpeichern(pNachricht);
        codierteMatrixAusgeben(text);
        String codierterText = verschluesseltenTextAuslesen(text);

        return codierterText;
	}
	
	private String verschluesseltenTextAuslesen(char[][] pCodierteMatrix) {
		
		String codierterText = "";

        for (int i = 0; i < zeilen; i++)
        {
            for (int j = 0; j < spalten; j++)
            {
                codierterText += pCodierteMatrix[i][j];
            }
        }

        return codierterText;
		
	}
	
}


import java.util.Scanner;

public class VerschluesselungTest {
	
	public static void main(String[] args) {
		
		String nachricht = "", codierteNachricht;
        int schluessel1 = 0, schluessel2 = 0;
        Verschluesselung verschluesselung;
        Scanner scanner = new Scanner(System.in);
        
        try {
		System.out.println("Geben Sie den zu verschlüsselnden Text ein:");
		nachricht = scanner.next();
		System.out.println("Schlüssel 1: ");
		schluessel1 = scanner.nextInt();
		System.out.println("Schlüssel 2: ");
		schluessel2 = scanner.nextInt();
	    }
		catch (IllegalArgumentException ex) {
			ex.getMessage();
		}
		
		verschluesselung = new Verschluesselung(schluessel1, schluessel2);
		
		codierteNachricht = verschluesselung.verschluessleText(nachricht);
		
		System.out.println("Ihr eingegebener Text in verschlüsselter Form:");
		System.out.println(codierteNachricht);
		
	}

}
```


----------

