• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Szyfrowanie podanego tekstu, szyfrem podstawieniowym C#

VPS Starter Arubacloud
0 głosów
2,201 wizyt
pytanie zadane 27 września 2019 w C# przez pitersooon98 Nowicjusz (200 p.)

Witam. Mam problem z następującym zadankiem: 

Napisz program, który szyfruje podany przez użytkownika tekst prostym szyfrem podstawieniowym zwanym „gaderypoluki”. Nazwa pochodzi od jednego z najczęściej używanych kluczy GA-DE-RY-PO-LU-KI. Klucz ten zawiera pary znakowych zamienników umieszczonych między myślnikami. Litery, których nie ma w kluczu pozostawia się w szyfrowanym tekście bez zmian. Przykładowo tekst „DRZEWO” po zaszyfrowaniu ma postać „EYZDWP”.

Napisałem już częściowo program, ale mam problem z tym, że druga pętla wykonuje się tylu krotnie, ile ma znaków szyfr (szyfr.Length). Chodzi mi o to, żeby podstawieniu literki, program zwiększył zmienną "a" i analizował a później z petli drugiej przeszedł do pierwszej. Liczę na jakieś wskazówki :) 

Console.WriteLine("Podaj tekst do zaszyfrowania: ");
            string tekst = Console.ReadLine();
            string szyfr = "GADERYPOLUKI";
            string tekstSzyfr = String.Empty;
            for (int a = 0; a < tekst.Length; a++)
            {
                for (int b = 0; b < szyfr.Length; b++)
                {
                    if (tekst[a] == szyfr[b]) //sprawdzenie czy literka z podanego tekstu wystepuje w szyfrze.
                    {
                        int indeks = szyfr.IndexOf(szyfr[a]); //sprawdzenie indeksu literki.
                        if (indeks % 2 == 0) //true to wartość parzysta. 

                            tekstSzyfr = tekstSzyfr + szyfr[indeks + 1];
                        else
                            tekstSzyfr = tekstSzyfr + szyfr[indeks - 1];
                        

                    }
                    else
                        tekstSzyfr = tekstSzyfr + tekst[a];
                    
                } 
            }
            Console.WriteLine(tekstSzyfr);
            Console.ReadKey();

 

3 odpowiedzi

+2 głosów
odpowiedź 27 września 2019 przez JakSky Stary wyjadacz (14,770 p.)
wybrane 27 września 2019 przez pitersooon98
 
Najlepsza

Napisałem takie coś:

Console.WriteLine("Podaj tekst do zaszyfrowania: ");
            string tekst = Console.ReadLine();
            string szyfr = "GADERYPOLUKI";
            string tekstSzyfr = String.Empty;
            tekst = tekst.ToUpper();
            for (int a = 0; a < tekst.Length; a++)
            {
                for (int b = 0; b < szyfr.Length; b++)
                {
                    if (tekst[a] == szyfr[b])
                    {
                       if(b % 2 == 0)
                       {
                            tekstSzyfr += szyfr[b+1];
                        }
                        else
                        {
                            tekstSzyfr += szyfr[b-1];
                        }
                      }
                   }
                   if(tekstSzyfr.Length-a == 0)
                   {
                      tekstSzyfr += tekst[a];
                    }
}
            Console.WriteLine(tekstSzyfr);
            Console.ReadKey();

Działa zgodnie z założeniem.

+1 głos
odpowiedź 27 września 2019 przez Siemił Mądrala (7,380 p.)
edycja 27 września 2019 przez Siemił
Na twoim miejscu zamiast szyfr trzymać w stringu stworzyłbym słownik. Potem analizujesz każdy znak z tekstu czy jest w słowniku.
+1 głos
odpowiedź 27 września 2019 przez gagyn Stary wyjadacz (11,050 p.)
edycja 27 września 2019 przez gagyn

Zacznijmy od tego, że pętla w pętli, a nich warunek w warunku (czterokrotne zagnieżdżenie) nigdy nie jest dobrym pomysłem.

Poczytaj o LINQ w C#, jest to bardzo złożone narzędzie i bardzo pomocne w takim przypadku co u Ciebie.

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/introduction-to-linq-queries

Oraz poczytaj o słownikach:

https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2?view=netframework-4.8

 

var szyfr = new Dictionary<char, char> {
  {'G', 'A'},
  {'D', 'E'},
  ...
};

Przykładowy kod może wyglądać tak:

Edit:

Przepraszam, ten poprzedni kod nie działa, bo string jest immutable (w przeciwieństwie do C++). Za chwilę podam inny kod.

 

komentarz 27 września 2019 przez JakSky Stary wyjadacz (14,770 p.)
edycja 27 września 2019 przez JakSky
Bez sensu używać LINQ czy słowników do tak małego ciągu. Więcej zajmie biblioteka LINQ niż cały kod to robiący. Gdyby tych par-kluczy było więcej to tak, jak najbardziej. Zapewne to przykład z jakiegoś zadania do przećwiczenia umiejętności posługiwania się pętlami i warunkami. :)
1
komentarz 27 września 2019 przez gagyn Stary wyjadacz (11,050 p.)

W sumie sam teraz widzę, że kod trochę długi się zrobił, ale wrzucam jak by to wyglądało w LINQ:

            string tekst = "DRZEWO";
            var szyfr = new Dictionary<char, char> {
                {'G', 'A'},
                {'D', 'E'},
                {'R', 'Y'},
                {'P', 'O' },
                {'L', 'U' },
                {'K', 'I' }
            };

            var nowyTekst = new StringBuilder();

            foreach (char t in tekst)
            {
                var item = szyfr.FirstOrDefault(s => s.Key == t || s.Value == t);
                
                if (item.Key == t)
                    nowyTekst.Append(item.Value);
                else if (item.Value == t)
                    nowyTekst.Append(item.Key);
                else
                    nowyTekst.Append(t);
            }

            Console.WriteLine(nowyTekst);

 

1
komentarz 27 września 2019 przez Siemił Mądrala (7,380 p.)

@JakSky, nie zgodze sie z Tobą. Biblioteka linq jest bardzo wydajna tak samo jak slownik. Natomiast korzystając ze słowników jest latwiejsze w czytaniu niż z indeksów w tablicach zgnierzdzonych w pętlch... 

komentarz 28 września 2019 przez JakSky Stary wyjadacz (14,770 p.)
ale nie w takim prostym przypadku
komentarz 28 września 2019 przez gagyn Stary wyjadacz (11,050 p.)
Ale lepiej uczyć się od początku, na prostych przykładach poprawnej składni. Po to jest nauka języka, żeby go dobrze poznać i robić tak jak się powinno.

Podobne pytania

0 głosów
1 odpowiedź 560 wizyt
pytanie zadane 7 września 2019 w C# przez Magikarp Początkujący (260 p.)
0 głosów
1 odpowiedź 369 wizyt
pytanie zadane 12 stycznia 2023 w C# przez DominikPie Użytkownik (770 p.)
0 głosów
0 odpowiedzi 568 wizyt
pytanie zadane 20 kwietnia 2020 w C i C++ przez Majster6918 Gaduła (4,030 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

61,853 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...