Zmiana pojedyńczych znaków w ciągu - szyfr

0

Mam zrobić program szyfrujący GADERYPOLUKI(prosty szyfr podstawieniowy). Poniżej kod, który napisałem ale coś nie działa - funkcja zwraca to samo co przyjmuje.

  1. Poradzi ktoś co jest źle ?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        public static class Gaderypoluki
        {
            public static string Encode(string key, string decodedText)
            {
                string encoded = decodedText;
                StringBuilder en = new StringBuilder(encoded);

                for (int i = 0; i < decodedText.Length; i++)
                {
                    for (int j = 0; j < key.Length; j++)
                    {
                        if (decodedText[i] == key[j])
                        {
                            if (j % 2 == 0)
                                en[i] = key[j + 1];
                            else
                                en[i] = key[j - 1];
                        }
                        
                    }

                }
                string encoded2 = en.ToString();
                return encoded2;
            }
        }
        
        
        
        static void Main(string[] args)
        {
            var key = "GADERYPOLUKI";
            var decodedText = "xyz abcd";
            var gadery = Gaderypoluki.Encode(key, decodedText);

            Console.WriteLine(gadery);

            Console.ReadKey();

        }
    }
} 
  1. Chciałbym też móc w taki sposób wywołać tą klasę:
Tuple<string, int[]> actual = Gaderypoluki.Encode(key, encodedText); 

Rozumiem że muszę w metodzie zwracać obiekt klasy Tuple? (teraz dostaję error że nie można skonwertować stringa na tuple)

2

Twój kod jest trochę nieprawidłowy. Nie sprawdzasz poprawności klucza, a jest kilka warunków, które należy spełnić żeby szyfr zadziałał. Najlepiej zdefiniować je w postaci wyjątków i wyrzucać kiedy program stwierdzi nieprawidłowość. Ja bym zrobił coś takiego:

using System;
using System.Text;
using System.Linq;

namespace Program {
    class Gaderypoluki {
        public class KeyIncorrectException : Exception {
            public string IncorrectionCause { get; private set; } 
            public KeyIncorrectException(string cause) {
                this.IncorrectionCause = cause;
            }
        }

        public static string Encrypt(string plain, string key) {
            if (key.Length % 2 == 0) {
                if (key.Length == key.Distinct().Count()) {
                    var encrypted = new StringBuilder(plain);
                    for (int i = 0; i < plain.Length; ++i)
                        for (int j = 1; j < key.Length; j += 2)
                            if (key[j] == plain[i]) encrypted[i] = key[j - 1];
                            else if (key[j - 1] == plain[i]) encrypted[i] = key[j];
                    return encrypted.ToString();
                }
                else throw new KeyIncorrectException("Characters in key must be unique!");
            }
            else throw new KeyIncorrectException("Incorrect key length! Key length must be even.");
        }

        public static string Decrypt(string encrypted, string key) {
            return Encrypt(encrypted, key);
        }
    }

    class Program {
        public static void Main(string[] args) {
            try {
                var plain = "Hello World";
                var key = "gaderypoluki";
                var encrypted = Gaderypoluki.Encrypt(plain, key);
                var decrypted = Gaderypoluki.Decrypt(encrypted, key);
                Console.WriteLine(encrypted);
                Console.WriteLine(decrypted);
            }
            catch(Gaderypoluki.KeyIncorrectException ex) {
                Console.WriteLine(ex.IncorrectionCause);
            }
        }
    }
}

Jak widać działa: http://ideone.com/08fmql

1

Ja wolę nieco inne podejście:

using System;
using System.Text;
using System.Linq;
 
namespace Program {
    class Gaderypoluki {
        private string key;
        private static string randKey(string seed) {
            string key;
            key="ab"; // tu jakaś sensowna generacja klucza na podstawie seed
            return key;
        }
        public Gaderypoluki(string key) {
            if((key==null)||(key.Length%2!=0)||(key.Length!=key.Distinct().Count())) {
            	key=randKey(key);
            }
            this.key=key;
        }
        public string Crypt(string plain) {
            if(plain==null) return null;
            var result=new StringBuilder(plain);
            for(int i=0;i<plain.Length;++i) {
                int k=key.IndexOf(plain[i]);
                if(k>=0) result[i]=(k%2==0?key[k+1]:key[k-1]);
            }
            return result.ToString();
        }
    } 
    class Program {
        public static void Main(string[] args) {
            var text="Hello World";
            var G=new Gaderypoluki("gaderypoluki");
            var encrypted=G.Crypt(text);
            var decrypted=G.Crypt(encrypted);
            Console.WriteLine(text);
            Console.WriteLine(encrypted);
            Console.WriteLine(decrypted);
        }
    }
}
0

Dzięki wielkie, szyfr działa tak jak chciałem.

Mam jeszcze zapisać liczbę wymian do tablicy o indeksie odpowiadającym danej sylabie. Indeksy muszą być w alfabetycznym porządku sylab w kluczu. np. dla klucza 'gade' pierwszy indeks powinien być 'de' a drugi 'ga'.

Wiem że pomiędzy if'ami muszę zliczać te wymiany, tylko że aby wyciągnąć indeksy tych sylab to muszę stworzyć nowego stringa i posortować w nim sylaby klucza?

1 użytkowników online, w tym zalogowanych: 0, gości: 1