Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Szyfr Cezara

Ostatnio zmodyfikowano 2014-12-28 15:07
Autor Wiadomość
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.
C/C++
#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.
P-123386
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ą
C/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.
P-123387
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'

C/C++
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;
        // 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;
       
        i++;
    }
}

Nie testowałem kodu, ale chyba powinien działać
P-123390
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.
P-123399
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

       
P-123404
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.
C/C++
#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;
        // 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;
       
        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.
P-123446
« 1 »
  Strona 1 z 1