[C++] deszyfrowanie szyfru afinicznego


(rafalski) #1

Witam!

Mam problem z odkodowaniem szyfru. Stosuje się do tych wzorów E(a,b,x)=a*x+b(mod 26), D(a,b,x)=a`*(x-b)(mod 26), ale chyba coś jest nie tak... Pewnie banał. Będę wdzięczny za pomoc.

#include 

#include 


using namespace std;


int main(int argc, char *argv[])

{

    string alfabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    int b=alfabet.size();

    string tekst="TOJESTZAKODOWANAWIADOMOSC";

    string codetable;

    string uncodetable;

    int a=tekst.size();

    string code, uncode;

    int k0=2;

    int k1=3;



    for (int i=0; i
    {

        codetable+=alfabet[(i*k1+k0)%26]; 

    }


    for (int i=0; i
    {

        for (int j=0; j
        {

            if (tekst[i]==alfabet[j])

            {

                                    code+=codetable[j];

            }

        }

    } 


    for (int i=0; i
    {

                  uncodetable+=codetable[(i*(k1-k0))%26]; //wzor odszyfrowujacy     

    }


    for (int i=0; i
    {

        for (int j=0; j
        {

            if (code[i]==codetable[j])

            {

                                    uncode+=uncodetable[j];

            }

        }

    }



    cout<
    

    system("PAUSE");

    return EXIT_SUCCESS;

}



[/code]

(Tomek Matz) #2

Wzór potrzebny do odszyfrowania tekstu podałeś prawidłowy, ale w kodzie używasz czegoś zupełnie innego. Błąd jest w tej linijce:

uncodetable+=codetable[(i*(k1-k0))%26]; //wzor odszyfrowujacy

Wszelkie informacje jakie potrzebujesz, żeby sobie poradzić z tym wzorem znajdziesz tutaj:

http://www.shodor.org/interactivate/discussions/CryptographyCipher/

W skrócie musisz uwzględnić sytuację, gdy wykonujesz operację modulo na liczbie ujemnej oraz musisz napisać kod wyznaczający a`.

Jak to zrobisz to będzie działać dobrze.


(rafalski) #3

no tak... to ja akurat wiem... tyle że nie mogę wymyśleć jak powinien wyglądać algorytm odszyfrowujący (ta feralna linijka), m.in problem sprawia to modulo, bo nie wiem jak je uwzględnić.


(Tomek Matz) #4

Właśnie dlatego podałem tamten link, bo tam jest wyjaśnione jak sobie z tym poradzić. No ale tu masz gotowca:

#include 


using namespace std;


int main(int argc, char *argv[])

{

    // http://www.shodor.org/interactivate/discussions/CryptographyCipher/


    string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    string text = "TOJESTZAKODOWANAWIADOMOSC";

    int a = 3;

    int b = 2;

    int aSize = alphabet.size();

    int tSize = text.size();

    string code, codetable, uncode, uncodetable;

    int c,d;


    for (int i = 0; i < aSize; i++)

    {

        codetable += alphabet[(i*a+b)%aSize];

    }


    for (int i = 0; i < tSize; i++)

    {

        for (int j = 0; j < aSize; j++)

        {

            if (text[i] == alphabet[j])

            {

                code += codetable[j];

            }

        }

    }


    for (int i = 1; i <= aSize; i++)

    {

        c = aSize*i+1;

        if (c%a == 0)

        {

            c /= a;

            break;

        }

    }


    for (int i = 0; i < aSize; i++)

    {

        d = (c*(i-b))%aSize;

        if (d < 0) d += aSize;


        uncodetable += codetable[d];

    }


    for (int i = 0; i < tSize; i++)

    {

        for (int j = 0; j < aSize; j++)

        {

            if (code[i] == codetable[j])

            {

                uncode += uncodetable[j];

            }

        }

    }


    cout<


    cin.get();

    return 0;

}

[/code]

EDIT:

Jeszcze jedno ... tekstu nie musisz mieć takiego zbitego. Możesz wprowadzić znak spacji do alfabetu i wówczas szyfrować wiadomość "TO JEST ZAKODOWANA WIADOMOSC". Należy tylko przy tym pamiętać, żeby największym wspólnym dzielnikiem a i ilości znaków w alfabecie było 1. W tym wypadku będziesz miał 27 znaków w alfabecie, czyli jako a możesz użyć np. 4 zamiast 3.