C# Frage zu "einfacher" Verschlüsselungs-Aufgabe (Polybios - Chiffrieren)

b0mMeL

Ensign
Registriert
Nov. 2012
Beiträge
193
Hey Leute, ich programmiere noch nicht lange und bin gerade dabei es für die Hochschule zu lernen...
und zwar habe ich ein paar Probleme bei folgender Aufgabe:


Ich soll ein Programm schreiben, was einen Text (String) einliest und dieser soll dann verschlüsselt werden.
A = 1, B = 2, C = 3.... Y/Z = 25 (je nach Kontext wird der richtige Buchstabe dann abgeleitet)

In der Aufgabenstellung sind zwei vorgegebene Funktionen:

static string polybios(string str);
static string polybios_zurueck(string str);

Die Funktionen sollen einen Text verschlüsseln und wieder entschlüsseln.


Zunächst mal meine bisherige Lösung:

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace Hausaufgabe_3
{
    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine("Bitte geben sie einen gewünschten Text ein:");
            string Texteingabe = Console.ReadLine();
            Console.WriteLine();
            Console.WriteLine("Der Text wird nun verschlüsselt");
            
            for (int i = 0; i < 3; ++i)
            {
                Thread.Sleep(1000);
                Console.Write(". . ");
            }

            Console.WriteLine();

            List<string> v = Polybios(Texteingabe);                                    

            Console.WriteLine();
            Console.WriteLine("Der Text wurde erfolgreich verschlüsselt");
            Console.WriteLine();
            Console.WriteLine("Der verschlüsselte Text lautet: ");
            Console.WriteLine();

            for (int i = 0; i < v.Count; i++)
            {
                Console.Write(v[i] + " ");
            }                               

            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("Um den Text wieder zu entschlüsseln, drücken Sie bitte eine beliebige Taste");
            Console.ReadKey();
            Console.WriteLine();
            Console.WriteLine("Der Text wird nun entschlüsselt");

            for (int i = 0; i < 3; ++i)
            {
                Thread.Sleep(1000);
                Console.Write(". . ");
            }

            Console.WriteLine();

            List<string> e = Polybios_Zurueck(v);                                      
            
            Console.WriteLine();
            Console.WriteLine("Der Text wurde erfolgreich entschlüsselt");
            Console.WriteLine();

            for (int i = 0; i < e.Count; i++)   // Warum gibt die Schleife nicht den entschlüsselten Text aus?!
            {
                Console.Write(e[i] + " ");
            }

            Console.ReadKey();
        }


        static List<string> Polybios(string str)                                        
        {
           
            List<string> Verschlüsselung = new List<string>();

            string[,] Alphabet = { 
                                    { "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" } 
                                 };

            string[,] Zahlen = { 
                                   { "1", "2", "3", "4", "5" }, 
                                   { "6", "7", "8", "9", "10" }, 
                                   { "11", "12", "13", "14", "15" }, 
                                   { "16", "17", "18", "19", "20" }, 
                                   { "21", "22", "23", "24", "25" } 
                               };

            for (int si = 0; si < str.Length; si++)                                     
            {
                for (int i = 0; i < 5; i++)
                {
                    for (int j = 0; j < 5; j++)
                    {
                        if (Alphabet[i, j] == str[si].ToString())                       
                        {
                            Verschlüsselung.Add(Zahlen[i, j]+" ");
                        }
                    }
                }
            }
            return Verschlüsselung;
        }



        static List<string> Polybios_Zurueck(List<string> str)                          
        {
            
            List<string> Entschlüsselung = new List<string>();

            string[,] Zahlen = { 
                                   { "1", "2", "3", "4", "5" }, 
                                   { "6", "7", "8", "9", "10" }, 
                                   { "11", "12", "13", "14", "15" }, 
                                   { "16", "17", "18", "19", "20" }, 
                                   { "21", "22", "23", "24", "25" } 
                               };

            string[,] Alphabet = { 
                                    { "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" } 
                                 };

            for (int si = 0; si < str.Count; si++)
            {
                for (int i = 0; i < 5; i++)
                {
                    for (int j = 0; j < 5; j++)
                    {
                        if (Zahlen[i, j] == str[si])
                        {
                            Entschlüsselung.Add(Alphabet[i, j]+" ");
                        }
                    }
                }
            }
            return Entschlüsselung;
        }   


    }
}


Folgende Fragen:

1. in der main methode wird am ende der entschlüsselte Text (letzte for-schleife) nicht ausgegeben. warum?!

2. Wie hätte ich das mit den vorgegebenen Funktionen lösen können?

Wie soll das ohne Liste überhaupt gehen? Weil spätestens bei der Verschlüsselungsfunktion Polybios(Texteingabe) bekäme ich ja einen String raus z.B. "1 1 2 2 10" => (A A B B J)

Und wenn ich jetzt den verschlüsselten Text in die Funktion Polybios_Zurueck() als Parameter setze um diesen Code wieder zu entschlüsseln in "A A B B J" dann könnt der ja z.B. die 10 nicht als 10 wahrnehmen, da ja jedes einzelne Char überprüft wird ob es die gleiche Zahl (String) ist wie bei string[ , ] Zahlen

Z.B.

if (string Zahlen [i, j] == str[si].ToString) (Konvertierung des Chars in ein String) Console.Write(Alphabet[i, j];

Sprich wenn (1 == 1) dann gebe Alphabet Buchstabe "A" aus

Aber wenn der jetzt eine 10 vergleichen will, dann wird die 10 ja nicht als ganzes betrachtet sondern aus 1 und 0. Und das Programm wird dann von char zu char vergleichen. Sprich zweistellige Zahlen lassen sich so nicht vergleichen.

Wie kann ich das also mit den Funktionen:

static string polybios(string str);
static string polybios_zurueck(string str);

lösen?

Bin für jede Hilfe dankbar! :)
LG
 
Zuletzt bearbeitet:
Auf die schnelle:

Folgende Fragen:

1. in der main methode wird am ende der entschlüsselte Text (letzte for-schleife) nicht ausgegeben. warum?!

EDIT: Nevermind, bin bei den Funktionen durcheinander gekommen.... /EDIT
Ich sehe, dass du die Daten als Liste einliest, aber der Funktion einen einzelnen String übergibst. Hier müsstest du dann auch die Liste übergeben.


2. Wie hätte ich das mit den vorgegebenen Funktionen lösen können?

Ich sehe da nur die Möglichkeit, jede Eingabe dem String anzuhängen bzw die Eingabe als String einzulesen.
Danach mit splitten jeden Buchstaben einzeln umzuwandeln und das jeweils dem Ausgabestring anzuhängen.
Dann müsstest du beim entschlüsseln das ganze wieder splitten, und zurückwandeln.

Ist keine allzuschöne Lösung, aber sollte funktionieren.

gruß
 
Zuletzt bearbeitet:
Hab mal die Verschlüsselung etwas kürzer und eleganter gelöst:

Code:
static string polybios(string str)
{
      string[] Matrix = new string[] { "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" };

      string output = "";
      char[] charArray = str.ToCharArray();

      for (int i = 0; i < charArray.Length; i++)
          output += (Array.IndexOf(Matrix, charArray[i].ToString())+1).ToString() + " ";

      return output.Trim();
}

vielleicht hilfts ja

Zurück ginge dann so:

Code:
static string Polybios_Zurueck(string str)
{
    int[] Matrix = new int[] { 65, 66, 67, 68, 69, 70, 71, 72, 73,
                        74, 75, 76, 77, 78, 79, 80, 81, 82, 
                        83, 84, 85, 86, 87, 88, 89 };
    string output = "";
    string[] strArray = str.Split(' ');

    for (int i = 0; i < strArray.Length; i++)
        output += Convert.ToChar(Matrix[Convert.ToInt32(strArray[i])-1]);

    return output;

}

Vorausgesetzt wird hier, dass die Eingabe nur aus den zulässigen Buchstaben von A bis Y besteht.
 
Zuletzt bearbeitet:
Okay danke, mir scheint, dass es mit meinen Funktionen viel angenehmer ist, das zu lösen, als mit den vorgegebenen. (Ob ich mich jetzt 100% an diese halten muss, ist glaube ich nichtmal notwendig, aber dennoch ist es interessant für mich, wie man es auf diese Art lösen könnte)

Ich steh gerade komplett auf den Schlauch warum die Konsole den entschlüsselten Text nicht ausgibt. Programmieren ist ja echt interessant, aber manchmal gehts mir so auf den Sack :D

EDIT:

Danke DocWindows
 
b0mMeL schrieb:
Ich steh gerade komplett auf den Schlauch warum die Konsole den entschlüsselten Text nicht ausgibt. Programmieren ist ja echt interessant, aber manchmal gehts mir so auf den Sack :D

Was gibt denn die Konsole aus? :D
 
1) Die Rückgabe erfolgt nicht, weil in deinem verschlüsselten Text ja z.b. "1 " steht (mit Leerzeichen), in deinem Zahlen-Alphabet zur Entschlüsslung aber "1" (ohne Leerzeichen). Und "1 " ist nicht gleich "1". Hier müsstest du entweder dein Zahlenalphabet anpassen, oder aber sowas nutzen wie
Code:
if (Zahlen[i,j] == str[si].Trim())

2) Wenn du statt einer List<string> einen Stringbuilder nutzt (enthalten in System.String, bräuchtest also eine using-Direktive mehr), dann kannst du am Ende einfach
Code:
static string Polybios(string str)
{
  StringBuilder Verschlüsselung
  ...
  for(...)
  {
    Verschlüsselung.Append(Zahlen[i,j] + " ");
  }
  ...
  return Verschlüsslung.ToString()
}
nutzen. Das funktioniert bei Listen übrigens NICHT, obwohl diese auch die Funktion haben. In der Entschlüsselung könntest du dann wieder eine Liste erzeugen (Damit deine Vergleichsfunktion gleich bleibt) indem du str.Split(' ') nutzt. Damit das letzte Element deiner Liste nicht leer ist, auch hier wieder der Tip:
Code:
str.Trim().Split()
um das zu umgehen. Trim() bewirkt, dass führende und schließende Leerzeichen entfernt werden. Bei dieser Variante hast du übrigens das Problem aus 1) nicht mehr.


Übrigens noch eine Info am Rande. Eine sehr viel elegantere Lösung wäre ein Dictionary und die Replace-Funktion zu benutzen, dann wird das Problem zu einem Zweizeiler. Diese Lösung würde ich dir aber erst geben, wenn du deinen Code zum Laufen bekommen hast, immerhin sollst du das Problem ja lösen ;)

@DocWindows: Auch eine elegantere Lösung, aber hast du an die Leerzeichen im Text gedacht? Seh ich auf den ersten Blick nicht.
 
aaaaahhhh!

Oh mein Gott, auf dieses Leerzeichen habe ich gar nicht geachtet :D Vielen Dank!

Es scheint also unzählige Befehle zu geben, die eine viel elegantere Lösung darstellen.
Ich bin die Aufgaben mit dem Wissen aus der Vorlesung und Übung angegangen.

EDIT:

Verschlüsselung.Add(Zahlen[i, j]+" ");

Entschlüsselung.Add(Alphabet[i, j]+" ");

bei den beiden Befehlen einfach das +" " entfernen und es funktioniert. Das Leerzeichen kann ich ja dann einfach bei der for-Schleife in der Main-Methode anhängen wenn ich die Liste ausgebe.


Werde jetzt nochmal eure Lösungen verinnerlichen. Vielen Dank nochmals für euere Hilfe!
 
Zuletzt bearbeitet:
Aber aufpassen! Das geht bei dir nur, weil du Listen verwendest (Die Listen-Trenner sind deine "Leerzeichen"). Wenn du auf strings umstellst, was ja in der Aufgabenstellung gefordert ist, darfst du die Leerzeichen nicht weglassen. Weil du sonst nicht mehr weißt, ob "11" jetzt "AA" oder "K" ist.
 
Zurück
Oben