do_matury Temat założony przez niniejszego użytkownika |
Szyfr Cezara » 2014-12-27 20:34:19 Witam wszystkich, zmierzyłem się z zadaniem implementacji szyfru Cezara w C++, w internecie widziałem kilka sposobów rozwiązania tego problemu, ale postanowiłem napisać swoją wersje, tak jak bym na maturze musiał zmierzyć się z tym problemem. Oczywiście musiałem posiłkować się pomysłami innych, ale nie do końca rozumiałem sposób ich działania. Udało mi się napisać coś takiego, kod działa, ale według mnie jest nie czytelny, chciałbym aby ktoś wyjaśnił mi jakąś najprostszą implementacje tego problemu, tak abym na maturze nie miał problemu. Oto mój kod, dla ułatwienia przyjąłem tylko wielkie litery. #include <iostream> #include <string> using namespace std; string szyfr( string txt, int klucz ) { int liczba = txt.length(); klucz = klucz % 26; for( int i = 0; i < liczba; i++ ) { if( klucz + txt[ i ] > 90 ) txt[ i ] =( txt[ i ] + klucz - 90 ) + 64; else if( klucz + txt[ i ] < 65 ) txt[ i ] = 91 -( 65 -( klucz + txt[ i ] ) ); else txt[ i ] = txt[ i ] + klucz; } return txt; } int main() { string tekst; int k; cout << "Podaj tekst do zaszyfrowania tylko duze litery: "; cin >> tekst; cout << "Podaj klucz szyfru: "; cin >> k; tekst = szyfr( tekst, k ); cout << tekst; return 0; }
Proszę o jakieś wskazówki i objaśnienie mi tego problemu w najprostszej postaci. |
|
do_matury Temat założony przez niniejszego użytkownika |
» 2014-12-27 21:13:56 W pewnej mądrej książce znalazłem taką funkcje szyfrującą void szyfruj( char tekst[], int klucz ) { int i = 0; klucz = klucz % 26; while( tekst[ i ] != '\0' ) { if(( int ) tekst[ i ] > 122 - klucz ) tekst[ i ] =( char )(( int ) tekst[ i ] + klucz - 26 ); else tekst[ i ] =( char )(( int ) tekst[ i ] + klucz ); i++; } }
Tylko nie wiem po co w if jest 122, a później odejmowane jest 26. |
|
Admixior |
» 2014-12-27 21:44:01 Zgodnie z tabelą ASCII 122 jest to znak 'z' (ostatni litera w tabeli) 26 to liczba znaków (inaczej 'z'-'a'+1) // bez "+1" byłby to ilość liter w przedziale od b do z, "+1" sprawia że literę 'a' też liczymy. Zakładam, że rozumiesz ideę działanie tego szyfru, więc: jeśli klucz będzie równy (przyjmijmy) 3 to wtedy dla: 'a' + 3 = 'd', bo 97+3 = 100 (patrz tabela ASCII) 'x' + 3 = '{', bo 120 + 3 = 123 żeby mieć tylko litery trzeba odjąć ilość liter, czyli to 26 jeżeli suma jest większa niż 122, czyli niż litera 'z' to: 'x' + 3 - ilosc_liter_w_alfabecie(26) = 'a' void szyfruj( char tekst[], int klucz ) { int i = 0; int ilosc_liter = 'z' - 'a' + 1; klucz = klucz % ilosc_liter; while( tekst[ i ] != '\0' ) { tekst[ i ] += klucz; if(( unsigned char ) tekst[ i ] > 'z' ) tekst[ i ] -= ilosc_liter; i++; } }
Nie testowałem kodu, ale chyba powinien działać |
|
do_matury Temat założony przez niniejszego użytkownika |
» 2014-12-27 22:47:57 Sprawdzałem kod i działa, ale tylko dla klucza dodatniego. Wiem, że w temacie popełniłem błąd, bo szyfr Cezara zakłada przesunięcie o trzy pozycje do przodu. Myślałem o szerszym ujęciu tego problemu i chciałem żeby dział także dla klucza ujemnego. |
|
darko202 |
» 2014-12-27 23:00:03 masz rozwiązanie w // w poniższej linijce jest rzutowanie, dlatego że wartości w tekst mogą wyjść ujemne po dodaniu klucza (np 'z'+10) if(( unsigned char ) tekst[ i ] > 'z' ) tekst[ i ] -= ilosc_liter;
pomyśl tylko co powinieneś zrobić al. np. 'a'-10
|
|
do_matury Temat założony przez niniejszego użytkownika |
» 2014-12-28 15:07:34 Ok, dzięki za pomoc, nareszcie to zrozumiałem. Napisałem coś takiego, i w pełni działa. #include <iostream> #include <string> using namespace std;
string szyfruj( string tekst, int klucz ) { int i = 0; int ilosc_liter = 'z' - 'a' + 1; klucz = klucz % ilosc_liter; while( tekst[ i ] != '\0' ) { tekst[ i ] += klucz; if(( unsigned char ) tekst[ i ] > 'z' ) tekst[ i ] -= ilosc_liter; if(( unsigned char ) tekst[ i ] < 'a' ) tekst[ i ] += ilosc_liter; i++; } return tekst; } int main() { string tekst; int k; cout << "Podaj tekst do zaszyfrowania tylko male litery: "; cin >> tekst; cout << "Podaj klucz szyfru: "; cin >> k; tekst = szyfruj( tekst, k ); cout << tekst; return 0; }
Jeszcze raz dzięki za pomoc i podpowiedzi. |
|
« 1 » |