• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Szyfr do rozgryzienia

Object Storage Arubacloud
0 głosów
536 wizyt
pytanie zadane 14 lutego 2017 w C i C++ przez kikosiak Obywatel (1,010 p.)

Witam!

Zrobiłem prosty szyfr i jestem ciekawy jak wygląda program deszyfrujący. Mam pewną koncepcję i zarys programu aczkolwiek nie działa :P. Mógłby ktoś mi pokazać jak wygląda kod do takiego programu?

Tu kod do programu szyfrującego:

#include <iostream>
#include <string>
#include <windows.h>
#include <time.h>
using namespace std;
string a,bin;
int c,liczba;

int main()
{
    cout << "Podaj wiadomosc xD:" << endl;
    getline(cin,a);
    c=a.length();
    int b[c],d[c];
     srand(time(NULL));
    liczba = rand()%50+1;

    for(int i=0; i<c; i++)
    {
    b[i]=a[i];
    b[i]-=liczba;
    cout<<b[i]<<"<-ascii"<<endl;
    while(b[i]){
  bin = (b[i]%2?"1":"0") + bin;
  b[i] /= 2;
 }

    }
    cout<<bin<<endl<<liczba;


    return 0;
}

 

komentarz 14 lutego 2017 przez JAKUBW Nałogowiec (33,470 p.)

Tak nie wolno!

int b[c],d[c];

Jest to wbrew zasadom C++!!!

komentarz 14 lutego 2017 przez kikosiak Obywatel (1,010 p.)
W takim razie oświeć mnie jak zrobić tablice z taka liczbom elementów jakie narzuci osoba która używa programu. :p

PS. Dopiero się uczę, zresztą jak widać.
komentarz 14 lutego 2017 przez JAKUBW Nałogowiec (33,470 p.)

Dynamicznie, przez wskaźnik

int * const b = new int[c];

Oraz na końcu korzystania zwalniasz pamięć:

delete [] b;

Jeżeli nie wiesz co to jest wskaźnik czy dynamicznie alokowanie pamięci to odpuść sobie. To wymaga już jakiejś wiedzy a ty podobno dopiero zaczynasz. Wrócisz do tego w późniejszym etapie nauki.

komentarz 14 lutego 2017 przez kikosiak Obywatel (1,010 p.)
Teoretycznie przepracowałem zakres wiedzy ze wskaźników itd. ale nie używam tego w moim kodzie wiem, że to błąd, ale chyba nie do końca jeszcze to rozumiem. Tak czy siak dzięki za uwagę i wyjaśnienie będę musiał się w to bardziej "wgryźć". :)
komentarz 14 lutego 2017 przez niezalogowany
Jak ich nie przećwiczysz przy tworzeniu programów to ich nigdy w pełni nie zrozumiesz.
komentarz 14 lutego 2017 przez Aisekai Nałogowiec (42,190 p.)
"Podaj wiadomość xD"

2 odpowiedzi

+1 głos
odpowiedź 14 lutego 2017 przez mokrowski Mędrzec (155,460 p.)
edycja 14 lutego 2017 przez mokrowski

Oprócz tego że program napisany z naruszeniem zasad programowania C++ (stosujesz VLA które są rozszerzeniem C99 i nie są częścią standardu C++), to szyfrowanie jest nieprawidłowe. Powodem nie jest to że stosujesz liczbę losową. Zapisujesz ją na wyjściu na końcu ciągu znaków i to jest ok bo umożliwia potencjalne odszyfrowanie ciągu. Problem leży w tym że odejmujesz liczbę z zakresu [1, 50] (linia 16).
Zakładając że kod ASCII znaku który wprowadzisz to min. 32 (spacja), oraz że kod to rzeczywiście jedynie ASCII (niedozwolone są litery narodowe w kodowaniach nie 8-bitowych), może dojść do wyliczenia liczby ujemnej (linia 21). Samo to nie jest problemem. Problemem jest reprezentacja bitowa tej liczby int. Może być ona różna na różnych komputerach (standard zakłada że to jest co najmniej 16 bit a może być więcej). Na wyjściu możesz mieć mniej lub więcej wartości "binarnych" 0/1 (u Ciebie i tak to znaki na konsoli). Tak więc Twój szyfrator/deszyfrator będzie działał wyłącznie na tej klasy komputerze i z tym kompilatorem którego będziesz używał do operacji w drugą stronę.

Następny błąd to przetwarzanie na wartości "binarne". Pętla od linii 23. Robisz to nieprawidłowo i w wyniku nie powstają napisy binarne ze stałą ilością znaków znaczących (zależnych od ilości bitów). To powoduje że wyliczenie gdzie jest ostatnia losowa liczba i gdzie kończy/zaczyna się odszyfrowywany znak staje się niemożliwe.

Chcesz żeby działał szyfrator? Najmniejsza poprawka to poprawienie tak aby był zgodny z C++ (radzę zastosować vector i zrezygnować z tablic), usunięcie zmiennych globalnych i wymuszenie typu na ograniczony bitowo (np int8_t z <cstdint>) oraz poprawienie konwersji do "napisu binarnego".

No i pamiętaj o założeniach które poczyniłem. Jeśli będziesz wprowadzał znaki narodowe, to psu na budę to co tu napisałem.

komentarz 14 lutego 2017 przez kikosiak Obywatel (1,010 p.)
Dzięki za tak wyczerpującą analizę. Czyli użycie tablicy ASCII jest niemożliwe jeśli chcę mieć polskie znaki? Oprócz tego jeśli chciałbym zostawić ten element z poruszaniem się po tablicy ASCII to zmniejszenie zakresu losowanej liczby np. do 31 będzie ok? Co do liczb binarnych to wyświetlenie ich w całości, znaczy rozumiem to tak, że każda liczba binarna musi mieć tyle samo znaków. Czyli chyba 7 w tym zakresie liczb powiedzmy od 1 do 95 po wzięciu pod uwagę, że będę odejmował od liczby 31. I tutaj nasuwa się pytanie czy zrobię to dobrze jeśli sprawdzę długość liczby binarnej i będę dopisywał 0 z przodu do momentu aż dana liczba będzie miała 7 cyfr?
komentarz 15 lutego 2017 przez mokrowski Mędrzec (155,460 p.)

Znaki ASCII, zapisane są w zakresie [0,127]. Są kodowania które przechowują znaki narodowe w zakresie [128, 255]. Takim kodowaniem dla naszego języka jest ISO8859-2. Wtedy będziesz mógł umieścić znaki narodowe w 1 bajcie. Ale to program ćwiczebny więc... radzę się tym ... nie zajmować ... teraz :-) Sugeruję pozostać przy ASCII.

Możesz (w celu początkowego ułatwienia), ograniczyć zakres losowanych liczb do [1,32], ale jak pisałem to nie jest główny problem. Wynik tych operacji odejmowania powinien być umieszczony w typie o stałej ilości bitów a nie w int który w zależności od platformy ma 16 lub więcej bitów.

Tak, dobrym rozwiązaniem jest poprawienie konwersji binarnej tak aby zwracała zawsze wszystkie bity liczby. Jeśli to 8 bitów, ma być 8 pozycji (a nie 7 jak pisałeś). 

Nie chcę Ci psuć zabawy z pisaniem konwersji. Dla celów diagnozy możesz sprawdzić z użyciem bitset czy dobrze dekodujesz:

#include <iostream>
#include <string>
#include <cstdint>
#include <bitset>

using namespace std;

int main() {
    cout << "Wprowadź napis ASCII (bez znaków narodowych: ";
    string napis;
    getline(std::cin, napis);
    cout << "Oto reprezentacje znaków ASCII\n";
    for(size_t i = 0; i < napis.size(); ++i) {
        cout << "Znak: |" << napis[i] << "| bin->|"
            << bitset<8>(napis[i]) << "| dec->|"
            << static_cast<int8_t>(napis[i]) << "|"<< endl;
    }
}

 

0 głosów
odpowiedź 14 lutego 2017 przez Barteck125 Obywatel (1,120 p.)
Obawiam się, ze program którego szukasz nie istnieje. W swoim programie korzystasz z pseudo losowych liczb które są pobieranie z cyklów procesora. Nie ma możliwość odnalezienia ich w zewnętrznym/innym programie, tak przypuszczam. Niech ktoś jeszcze się wypowie :) bo być może źle myślę. Pozdrawiam
komentarz 14 lutego 2017 przez Barteck125 Obywatel (1,120 p.)
Zauważ też że to samo słowo "zakodowane", za każdym razem wygląda inaczej :)
komentarz 14 lutego 2017 przez kikosiak Obywatel (1,010 p.)
W takim razie dajmy na to, że program zna tą liczbę,podajemy ją w zmiennych.
komentarz 14 lutego 2017 przez Barteck125 Obywatel (1,120 p.)
W obecnej sytuacji ta liczba będzie się za każdym razem zmieniać tzn. jest ona za każdym razem inna, więc podanie jej w programie deszyfrujacym będzie bez sensu. Musisz trochę uprościć ten kod albo skomplikować ale w schematyczny sposób. Używanie licz pseudo losowych szyfruje Twoj program w taki sposób ze nawet Ty jako twórca tego szyfru nie będziesz w stanie go odkodować, a chyba nie taki był zamiar :)

Podobne pytania

0 głosów
0 odpowiedzi 483 wizyt
0 głosów
0 odpowiedzi 10,719 wizyt
0 głosów
1 odpowiedź 1,494 wizyt
pytanie zadane 2 grudnia 2017 w C i C++ przez Krystek102 Bywalec (2,440 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...