Program szyfrujący, C++. Losowanie znaków.

0

Witam.

Mam za zadanie zrobić w C++ program szyfrujący. Szyfrowanie już zrobiłem tylko mam problem z deszyfrowaniem i na moje oko nie da się tego odszyfrować i nauczyciel musiał się pomylić, ale do rzeczy.

Szyfrowanie polega na tym:

Użytkownik wpisuje dowolny tekst np ,napis'. W programie jest baza znaków ,abcdefghijklmnoprstuwz123456789' i program sprawdza każdy znak w tekście wprowadzonym przez użytkownika np. ,n' jest na pozycji 13, ,a' na 0 itp. Następnie losowane są liczby np. 2,3,10,22. Te liczby dodawane są do pozycji tych znaków: n = 13 + 2 = 15, a= 0 + 3 = 3. Takie gotowe liczby służą do ułożenia szyfru np. 15 odpowiada znakowi "P" w bazie znaków a 3 opowiada ,d' i tak powstaje szyfr. Problem jest z odszyfrowywaniem... na moje oko jest możliwość odszyfrowania ale będzie potrzebny i szyfr i liczby które został wylosowane.

Np. po wpisaniu tego szyfru: p d i wylosowanych liczb: 2 , 3 program wykonuje taką czynność że sprawdza na której pozycji jest "P" w tym przypadku na 15 a ,d' na 3. Odejmuje 15 - 2 = 13, 3 - 3 = 0, i wszystko się zgadza 13 odpowiada ,n' a 0 odpowiada ,a'.

Kłopot w tym gdy wylosowane liczby po dodaniu do pozycji danych znaków będą większe niż 31 czyli więcej niż jest znaków w stringu ze znakami... Na początku gdy ta liczba była większa to program nie znajdywał danego znaku na tej pozycji i dawał jakiś dziwny znaczek w stylu serduszka itp. Rozwiązałem ten problem poszerzając
string = ,abcdefghijklmnoprstuwz123456789abcdefghijklmnoprstuwz123456789' o kilka razy. Ale to problemu nie rozwiązało gdyż później pojawiły się problemy z odszyfrowywaniem. Weźmy np. że znakowi
n = 15, wylosowano liczbę 30 co po dodaniu daje 45, ta liczba odpowiada znakowi ,,o'' w moim poszerzonym stringu. Jednak gdy przychodzi pora odszyfrowywania i zostaje wpisany znak i wylosowana liczba: o, 30. Program znak o wyczytuje na pozycji 14!!!! Gdyż bierze pierwszą pozycję a to już uniemożliwia prawidłowe odszyfrowanie, gdyż po odejmowaniu wynik będzie inny niż powinien.

Nie wiem czy ktoś dotrwał do końca, nie wiem czy ktoś zrozumiał to co napisałem, ale jeśli taka osoba się znajdzie to proszę o pomoc. Nie chcę gotowego rozwiązania... nie chcę by ktoś za mnie odwalił zadanie... chcę tylko jakąś małą rade bo ślęczę i myślę nad tym już kilka godzin i nie mogę nic wymyślić.

Etap szyfrowania udało mi się zrobić, jeśli by komuś był potrzebny kod do szyfrowania to mogę wkleić.

Z góry dziękuję za pomoc.

2
char Alphabet[]="abcdefghijklmnoprstuwz123456789";
char ch='z';
int key=27;
ch=Alphabet[(strchr(Alphabet,ch)-Alphabet+key)%(sizeof(Alphabet)-1)];

Następnym razem postaraj się streścić pytanie do jednego ewentualnie dwóch zdań, ja z trudem się zmusiłem do przeczytania tego wypracowania.

0

Żeby odszyfrować tekst musisz podać zarówno ten zaszyfrowany, jak i szyfr za pomocą którego został on zaszyfrowany, wtedy od tekstu odejmujesz po kolei kolejne elementy szyfru i powinno się zgadzać.
A jeśli chodzi o ograniczenie długości tablicy : Jeżeli dodasz jakąś tam sobie liczbę i wyjdzie Ci poza zakres, podziel otrzymaną liczbę modulo przez długość tablicy-1. Tym samym indeks "powróci" na początek tablicy i znajdzie prawidłowy znak. Analogicznie, ale odwrotnie ( :P ) dla deszyfrowania.

EDIT: 2 sekundy spóźnienia?!

0

Dziękuję wam za odpowiedź, ale nie bardzo łapie o co chodzi.... 13th_Dragon jak byś mógł wyjaśnić o co w tym chodzi? Ja może CI pokaże jak to u mnie wygląda:

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>
#include "klasy.h"
using namespace std;


int program_szyfrujacy::liczby[33]  = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,21,22,23,24,25,26,27,28,29,30,31};
std::string program_szyfrujacy::znaki = "abcdefghijklmnoprscuwz-123456789abcdefghijklmnoprscuwz-123456789abcdefghijklmnoprscuwz-123456789";
int main()
  {
  srand( time( NULL ) );
  program_szyfrujacy enigma;
  enigma.menu();
  int opcja;
  cin >> opcja;
  cin.ignore();
  switch (opcja)
  {
      case 1:
      {
         system ("cls");
         cout << "Podaj tekst do zaszyfrowania. Zamiast spacji uzyj znaku '-':  ";
         getline (cin,enigma.tekst);
         enigma.dlugosc = enigma.tekst.length();
         cout << "\a";
         cout << "\n";
         cout << "Wylosowano liczby. UWAGA! Liczby te beda potrzebne do odszyfrowania wiadomosci i sa czescia szyfru!!!! :  " << endl;
         cout <<"\nLiczby: ";
         for (int i = 0; i < enigma.dlugosc; i++)
         {
             enigma.wylosowane[i] = enigma.losowanie();
             cout << enigma.wylosowane[i] << " ";
         }

         cout << "\n\n";
         for (int i = 0; i < enigma.dlugosc; i++)
         {
         std::string strznak(enigma.tekst,i,1);
         size_t pozycja = enigma.znaki.find (strznak);
         enigma.pozycje_znakow[i] = pozycja;
         cout << enigma.pozycje_znakow[i] << " ";

         }
         cout << "\n\n";
         for (int i = 0;i < enigma.dlugosc; i++)
         {
            enigma.gotowe_liczby[i] = enigma.pozycje_znakow[i] + enigma.wylosowane[i];
            cout << enigma.gotowe_liczby[i] << " ";
         }
         cout << "\n\n" << endl;
         cout << "Twoj szyfr to: ";
         for (int i = 0; i < enigma.dlugosc; i++)
         {
             enigma.zaszyfrowane[i] = enigma.znaki[enigma.gotowe_liczby[i]];
             cout << enigma.zaszyfrowane[i];
         }
         break;
      }
      case 2:
        {
            system ("cls");

        }
        break;
  }
  }

dodanie znacznika <code class="cpp"> - fp

2

potrzebujesz przesunięcia cyklicznego, załóżmy że masz znaki tylko '0'..'9' a przesunięcie mas 39
7+39=46
46%10=6
więc kodowanie '7' za pomocą liczby 39 to '6'

0

Achaaaaa dzięki teraz to powinno działać. Ja to u siebie w kodzie zrobiłem tak:

for (int i = 0;i < enigma.dlugosc; i++)
         {
           enigma.gotoweliczb[i] = 31%enigma.gotowe_liczby[i];
         }

Ale żeby odszyfrować tą wiadomość to nadal będę potrzebował i szyfru i liczb które wylosował program prawda??

dodanie znacznika <code class="cpp"> - fp

0

To:

dejmien napisał(a):
for (int i = 0;i < enigma.dlugosc; i++)
         {
           enigma.gotoweliczb[i] = 31%enigma.gotowe_liczby[i];
         }

nie ma nic a nic wspólnego z tym o czym mówiłem.

0

No ale działa to na tej zasadzie: tablica gotowe_liczby przechowuje już gotowe liczby, które zostały już do siebie dodane następnie obliczana jest reszta z dzielenia liczby 31 bo tyle jest znaków w bazie znaków.
Na razie spełnia to swoje zadanie... to co zmienić to??

int key=27;
ch=Alphabet[(strchr(Alphabet,ch)-Alphabet+key)%(sizeof(Alphabet)-1)];

Weźmy to co ty podałeś...
zmienna key=27 od czego jest ?

strchr ma zwrócić pozycję na której znajduje się dany znak prawda? Argymenty alphabet to tekst z ktorego ma wyszukiwać dany znak a ch oznacza jaki to ma być znak w tym przypadku 'z' tak? Dalej nie rozumiem.

dodanie znacznika <code class="cpp"> - fp

0

To wczytaj się w to co napisałeś w wypracowaniu na początku tematu, tam wszystko jest opisane.

0

Ok dzięki wielkie za okazaną pomoc :-) Myślę że jakoś sobie poradzę.

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