IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Lolindir
Člen
Avatar
Lolindir:12.1.2019 17:44
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Playfair
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        string OT = string.Empty;
        string osetrenyOT = string.Empty;
        string jazyk = "CZ";
        char prvniNahrada = new char();
        char druhaNahrada = new char();
        char[] vysledek = new char[25];
        char[] sDiakritikou = "ĚŠČŘŽÝÁÍÉÚŮŤĎŇ".ToCharArray();
        char[] bezDiakritiky = "ESCRZYAIEUUTDN".ToCharArray();
        char[] abeceda = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
        char[,] tabulka = new char[5,5];
        int m = new int();

        public static string OdstranDiakritiku(string Text)
        {
            string stringFormD = Text.Normalize(System.Text.NormalizationForm.FormD);
            System.Text.StringBuilder retVal = new System.Text.StringBuilder();
            for (int index = 0; index < stringFormD.Length; index++)
            {
                if (System.Globalization.CharUnicodeInfo.GetUnicodeCategory(stringFormD[index]) != System.Globalization.UnicodeCategory.NonSpacingMark)
                    retVal.Append(stringFormD[index]);
            }
            return retVal.ToString().Normalize(System.Text.NormalizationForm.FormC);
        }

        private void tB_vstupniKlic_TextChanged(object sender, EventArgs e)
        {
        }
        private void buttonPrevod_Click(object sender, EventArgs e)
        {
            bool OTprazdny = string.IsNullOrEmpty(OT);
            if (OTprazdny == false)
            {

            }
            OT = tB_vstupniKlic.Text;
        //tabulka = new char[5,5];

            if (jazyk == "CZ")
            {
                prvniNahrada = 'W';
                druhaNahrada = 'V';
            }
            if (jazyk == "EN")
            {
                prvniNahrada = 'J';
                druhaNahrada = 'I';
            }
            osetrenyOT = OdstranDiakritiku(OT).ToUpper();
            /*
            if (osetrenyOT.ToUpper().ToCharArray().Except(abeceda).Count() > 0)
            {
                tB_vstupniKlic.Text = String.Empty;
                OT = String.Empty;
                System.Diagnostics.Process.Start(Application.ExecutablePath); // to start new instance of application
                this.Close(); //to turn off current app
                return;
            }
            */
            string bezDuplikatu = string.Join("", osetrenyOT.ToCharArray().Distinct());

            if (bezDuplikatu.Contains('W') && jazyk == "CZ")
            {
                bezDuplikatu = bezDuplikatu.Replace(prvniNahrada, druhaNahrada);
                bezDuplikatu = string.Join("", bezDuplikatu.ToCharArray().Distinct());
            }
            if (bezDuplikatu.Contains('J') && jazyk == "EN")
            {
                bezDuplikatu = bezDuplikatu.ToString().Replace(prvniNahrada, druhaNahrada);
                bezDuplikatu = string.Join("",bezDuplikatu.ToCharArray().Distinct());
            }

            abeceda = new string(abeceda).Replace(prvniNahrada, druhaNahrada).ToCharArray();
            vysledek = bezDuplikatu.Union(abeceda.Except(bezDuplikatu).ToArray()).ToArray(); //ošetřená klíčová tabulka formou Array
            m = 0;
            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    if (m < 24 && vysledek[m] == prvniNahrada)
                    {
                        m++;
                    }
                    if (m < 25)
                    {
                        tabulka[i, j] = vysledek[m++];
                    }
                }
            }

            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    tB_vyslednyText.AppendText("" + tabulka[j, 0]+ " | " + tabulka[j, 1] + " | " + tabulka[j, 2] + " | " + tabulka[j, 3]+ " | " + tabulka[j, 4]);
                    tB_vyslednyText.AppendText(Environment.NewLine);
                    tB_vyslednyText.Font = new Font(FontFamily.GenericMonospace, tB_vyslednyText.Font.Size);
                }
            }
        }

        private void tB_vyslednyText_TextChanged(object sender, EventArgs e)
        {

        }

        private void rB_JazykCZ_CheckedChanged(object sender, EventArgs e)
        {
            if (rB_JazykCZ.Checked == true)
            {
                jazyk = "CZ";
                /*
                prvniNahrada = 'W';
                druhaNahrada = 'V';
                */
            }
        }

        private void rB_JazykEN_CheckedChanged(object sender, EventArgs e)
        {
            if (rB_JazykEN.Checked == true)
            {
                jazyk = "EN";
                /*
                prvniNahrada = 'J';
                druhaNahrada = 'I';
                */
            }
        }
    }
}

Při přepnutí jazyka z jednoho na druhý jde proměnná m mimo hranice pole

Zkusil jsem: Resetovat program při změně jazyka
Měnit jazyk jinde v programu

Chci docílit: Naprogramovat playfairovu šifru dle tohoto návodu
Návod

Je velice možné že některé pasáže v mém kódu jsou zbytečné, či přehnaně složité. Programování mi zatím moc nejde, momentálně se snažím přežít druhý ročník studia Softwarového Inženýrství

Editováno 12.1.2019 17:47
 
Odpovědět
12.1.2019 17:44
Avatar
HONZ4
Člen
Avatar
HONZ4:13.1.2019 13:52

Zběžně jsem se díval na ten kód, tady jsem našel místo, kde hrozí riziko:

if (m < 25) //pokud tady bude 24
{
 tabulka[i, j] = vysledek[m++]; //tady se bude přistupovat k  vysledek[25];
}

To pole vysledek má pouze 25 prvků, takže max. index je 24!

Editováno 13.1.2019 13:54
 
Nahoru Odpovědět
13.1.2019 13:52
Avatar
Lolindir
Člen
Avatar
Odpovídá na HONZ4
Lolindir:13.1.2019 13:57

Velice děkuji. Můžu se zeptat, jak bych to mohl opravit?

 
Nahoru Odpovědět
13.1.2019 13:57
Avatar
HONZ4
Člen
Avatar
Odpovídá na Lolindir
HONZ4:13.1.2019 14:13

Mě se ta šifra nechce studovat. Takže nevím co to má dělat.
Buďto zvětši pole,

char[] vysledek = new char[26];

nebo zmenši rozsah.:

if (m < 24)
{
 tabulka[i, j] = vysledek[m++];
}
Editováno 13.1.2019 14:13
 
Nahoru Odpovědět
13.1.2019 14:13
Avatar
HONZ4
Člen
Avatar
HONZ4:13.1.2019 14:21

Omlouvám se. Kecám. Ty to máš vlastně dobře. Nejprve se načte a až pak přiřadí..

 
Nahoru Odpovědět
13.1.2019 14:21
Avatar
HONZ4
Člen
Avatar
Odpovídá na Lolindir
HONZ4:13.1.2019 14:43

Tak jsem si to zkusil. Něco s toho vyleze. Je to bez chybových hlášení.

 
Nahoru Odpovědět
13.1.2019 14:43
Avatar
Odpovídá na Lolindir
Matúš Olejník:13.1.2019 14:46
m = 0;
for (int i = 0; i < 5; i++)
{
    for (int j = 0; j < 5; j++)
    {
        if (m < 24 && vysledek[m] == prvniNahrada)
        {
            m++;
        }
        if (m < 25)
        {
            tabulka[i, j] = vysledek[m++];
        }
    }
}

Tu keď ti bude platiť prvá podmienka if (m < 24 && vysledek[m] == prvniNahrada) v ktorej dávaš m++ tak ti určite (skoro vždy) bude platiť aj druhá podmienka if (m < 25) v ktorej tiež inkrementuješ m takže hodnota v m môže byť ďaleko väčšia ako 24 a v tom prípade ideš mimo hranice pola vysledek. Takže tam sa zameraj na opravu.

Editováno 13.1.2019 14:48
Nahoru Odpovědět
13.1.2019 14:46
/* I am not sure why this works but it fixes the problem */
Avatar
Odpovídá na Matúš Olejník
Neaktivní uživatel:13.1.2019 16:38

Tu keď ti bude platiť prvá podmienka if (m < 24 && vysledek[m] == prvniNahrada) v ktorej dávaš m++ tak ti určite (skoro vždy) bude platiť aj druhá podmienka if (m < 25) v ktorej tiež inkrementuješ m takže hodnota v m môže byť ďaleko väčšia ako 24 a v tom prípade ideš mimo hranice pola vysledek. Takže tam sa zameraj na opravu.

Počkej, můžeš mi vysvětlit, co na tom má špatně? Pokud jsem ten kód pochopil dobře, tak v případě, že je na daném místě <code>prvniNah­rada</code> (znak, kterého se potřebuje zbavit), tak prostě zvětší <code>m</code>. Ve druhé podmínce si znovu ověřuje, zda múže <code>m</code> použít (i když zrovna pevná hodnota není nejšťastnější řešení).

Lolindir když jsem to procházel, zdálo se mi, že je to v naprostém pořádku (teda až na přehlednost). Btw. řekl bych, že v první podmínce v kódu, co zmiňoval Matúš, ani tu 24 nepotřebuješ.

Nahoru Odpovědět
13.1.2019 16:38
Neaktivní uživatelský účet
Avatar
Odpovídá na Neaktivní uživatel
Matúš Olejník:14.1.2019 9:37

Ahoj, keď som to pozeral cez mobil tak som si veľmi nevšimol, že pred tým cyklom nahrádza nejaké písmená za iné takže táto podmienka vysledek[m] == prvniNahrada v tomto prípade nikdy nebude platiť , čiže sa tam nikdy neinkrementuje m až o 2 v jednom cykle. Ďakujem za pripomienku :)

Nahoru Odpovědět
14.1.2019 9:37
/* I am not sure why this works but it fixes the problem */
Avatar
Odpovídá na Neaktivní uživatel
Michal Štěpánek:14.1.2019 12:17

Nevím přesně, co by to mělo dělat, ale podle mě se povedou skoro vždy obě ty podmínky, tzn., že v té druhé se bude znovu inkrementovat to již jednou navýšené "m" z předchozí podmínky. Myslím, že by tam mělo být "else if", tedy v případě, že se m=24 spustit druhou podmínku.
Pokud to ovšem nemá být účelem (ta dvojitá inkrementace)...

Nahoru Odpovědět
14.1.2019 12:17
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Odpovídá na Michal Štěpánek
Matúš Olejník:14.1.2019 12:37

Na to som narážal pôvodne aj ja, ale ešte pred tým cyklom má

abeceda = new string(abeceda).Replace(prvniNahrada, druhaNahrada).ToCharArray();
vysledek = bezDuplikatu.Union(abeceda.Except(bezDuplikatu).ToArray()).ToArray();

čím vlastne z vysledek vymaže znak z prvniNahrada a teda tá prvá podmienka nikdy nebude platiť :D

Nahoru Odpovědět
14.1.2019 12:37
/* I am not sure why this works but it fixes the problem */
Avatar
Odpovídá na Michal Štěpánek
Neaktivní uživatel:14.1.2019 18:38

Možná by ještě bylo přece jen dobré si ten článek přečíst. Pak to budeš chápat naprosto bez problému.
Ve zkratce: máš heslo, za něj přidáš abecedu, odstraníš duplikáty, a protože z toho potřebuješ čtverec (5 × 5), musíš jedno písmeno „vyrazit“. V originále je to J (místo něj I), ale v češtině je logičtější W a V.

Matúš Olejník Tak toho jsem si přes všechen ten kód ani nevšiml (teda zapomněl jsem na to), díky.

Nahoru Odpovědět
14.1.2019 18:38
Neaktivní uživatelský účet
Avatar
Lolindir
Člen
Avatar
Lolindir:14.1.2019 21:23

Proč tedy můj kód funguje jak má, ale pouze do chvíle než přepnu jazyk?

Pokud na začátku zvolím jazyk EN, a teprve potom zadám slovo, tak program funguje jak má.
Pokud na začátku zvolím jazyk CZ, a pak zadám slovo, tak program také funguje jak by měl.
Problém nastává, když už je jeden jazyk zvolený, a chci zvolit jiný. Do jeho abecedy už se totiž nedostanou písmena, které mají vypadnout v abecedě v případě druhého jazyka.

 
Nahoru Odpovědět
14.1.2019 21:23
Avatar
HONZ4
Člen
Avatar
Odpovídá na Lolindir
HONZ4:15.1.2019 17:37

co si přesně myslíš že dělá toto:

vysledek = bezDuplikatu.Union(abeceda.Except(bezDuplikatu).ToArray()).ToArray();
a co od toho čekáš?

použij přesně toto a uvidíš, že to bude fungovat:

private void buttonPrevod_Click(object sender, EventArgs e)
{
    tB_vyslednyText.Clear();
    bool OTprazdny = string.IsNullOrEmpty(OT);
    if (OTprazdny == false)
    {

    }
    OT = tB_vstupniKlic.Text;
    //tabulka = new char[5,5];
    string bezDuplikatu = string.Join("", osetrenyOT.ToCharArray().Distinct());



    if(jazyk == "CZ")
    {
        prvniNahrada = 'W';
        druhaNahrada = 'V';
        if (bezDuplikatu.Contains('W'))
        {
            bezDuplikatu = bezDuplikatu.Replace(prvniNahrada, druhaNahrada);
            bezDuplikatu = string.Join("", bezDuplikatu.ToCharArray().Distinct());
        }
    }
    else//jazyk EN
    {
        prvniNahrada = 'J';
        druhaNahrada = 'I';
        if (bezDuplikatu.Contains('J'))
        {
            bezDuplikatu = bezDuplikatu.ToString().Replace(prvniNahrada, druhaNahrada);
            bezDuplikatu = string.Join("", bezDuplikatu.ToCharArray().Distinct());
        }
    }


    abeceda = new string(abeceda).Replace(prvniNahrada, druhaNahrada).ToCharArray();
    vysledek = bezDuplikatu.Union(abeceda.Except(bezDuplikatu).ToArray()).ToArray(); //ošetřená klíčová tabulka formou Array
    m = 0;
    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            if (m < vysledek.Length-1 && vysledek[m] == prvniNahrada)
            {
                m++;
            }
            if (m < vysledek.Length)
            {
                tabulka[i, j] = vysledek[m++];
            }
        }
    }

    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            tB_vyslednyText.AppendText("" + tabulka[j, 0] + " | " + tabulka[j, 1] + " | " + tabulka[j, 2] + " | " + tabulka[j, 3] + " | " + tabulka[j, 4]);
            tB_vyslednyText.AppendText(Environment.NewLine);
            tB_vyslednyText.Font = new Font(FontFamily.GenericMonospace, tB_vyslednyText.Font.Size);
        }
    }
}

ten kód jsem schválně moc neměnil, abys se vtom vyznal.

Není náhodou problém i v tom, že před spuštění nové akce nevymažeš výstupní textbox?

Editováno 15.1.2019 17:39
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
15.1.2019 17:37
Avatar
Lolindir
Člen
Avatar
Odpovídá na HONZ4
Lolindir:19.1.2019 15:08

Velice děkuji, pravděpodobně to vyřešilo všechny mé problémy. Přidal jsem už i vymazání vstupního textboxu na začátku, čehož jsem si dřív nevšiml.

Dále nahrazení m < 24 za m < vysledek.Length i o pár řádků níž vyřešilo můj druhý problém, což jsem si dřív neuvědomil.

Velice děkuji za čas a ochotu všech kteří mi nabídli pomoc. Těší mě, že přispíváte k zlepšování mých programovacích schopností :)

 
Nahoru Odpovědět
19.1.2019 15:08
Avatar
Lolindir
Člen
Avatar
Odpovídá na Lolindir
Lolindir:19.1.2019 15:11

Narazil jsem však ještě na jeden problém:

V případě kdy zadám tento náhodný řetězec jako klíč, uqiweuwo (proměnná OT):
vygenerovaná tabulka pak vypadá takto:
U | Q | I | V | E
O | A | B | C | D
F | G | H | K | L
M | N | P | R | S
T | X | Y | Z | Z

Což je problém. Tabulka nesmí obsahovat stejné znaky, a musí být vždy rozměru 5x5, se znaky klíče které se neopakují jinde v tabulce + se zbytkem abecedy. Mohu se zeptat co mi zde uniká?

Editováno 19.1.2019 15:12
 
Nahoru Odpovědět
19.1.2019 15:11
Avatar
Lolindir
Člen
Avatar
Lolindir:19.1.2019 15:28

Oprava: Tato tabulka vznikne při přepnutí jazyka z CZ na EN a poté zpět na CZ. Při prvním vygenerování jen CZ jazyka a poté i EN jazyka, vznikne tabulka jak má.

 
Nahoru Odpovědět
19.1.2019 15:28
Avatar
Lolindir
Člen
Avatar
Odpovídá na Lolindir
Lolindir:19.1.2019 16:55

Zjistil jsem že problém je v tom, když z CZ jazyka přepnu na EN a poté zpět na CZ, program začne brát v úvahu obě pravidla náhrady písmen, které ale nesmí platit současně.

Český jazyk:
W -> V

Anglický jazyk
J -> I

Při přepnutí jazyka v pořadí CZ -> EN -> CZ se na písmena ve Vysledek[] aplikují pravidla jak z CZ jazyka tak EN. Ve výsledku je tedy nakonec o jedno písmeno méně, jelikož ho odstranilo pravidlo z druhého jazyka, které se ale v tomto případě nemělo aplikovat.

Dokázal by mi někdo poradit, jak bych toto mohl vyřešit?

Editováno 19.1.2019 16:56
 
Nahoru Odpovědět
19.1.2019 16:55
Avatar
Odpovídá na Lolindir
Matúš Olejník:19.1.2019 17:36
abeceda = new string(abeceda).Replace(prvniNahrada, druhaNahrada).ToCharArray();

Premennú abeceda máš ako globálnu premennú. Najprv máš celú abecedu, keď je jazyk CZ vyradíš z nej W keď prepneš na EN tak z tej abecedy kde už chýba W vyradíš ešte I. Daj ju ako lokálnu premennú alebo nejako resetuj do pôvodného stavu. Ak nepomôže hoď sem aktuálny kód už sa v tom strácam keďže je to tu poskladané z viacerých príspevkov :)

Nahoru Odpovědět
19.1.2019 17:36
/* I am not sure why this works but it fixes the problem */
Avatar
Lolindir
Člen
Avatar
Lolindir:19.1.2019 17:38

Ano, to vyřešilo můj problém. Velice děkuji :)

Editováno 19.1.2019 17:41
 
Nahoru Odpovědět
19.1.2019 17:38
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 20 zpráv z 20.