Wczytywanie z pliku i koniec pliku

0

Witam,
Obecnie pisze szyfr stumieniowy, ktory ma za zadanie zapisywac do pliku zaszyfrowany tekst(kod ASCII).
Kiedy wczytuje plik z zaszyfrowanym tekstem moge go wczytac jedynie do pierwszego znaku konca pliku EOF, ktory zostal utworzony przy szyfrowaniu. Nie wiem jak moge wczytac cala zawartosc pliku do tablicy char*. Gdy daje w warunku petli wczytujacej dalej niz pierwszy napotkany znak EOF petla przechodzi dalej, lecz do mojej tablicy char* nic sie juz nie wczytuje. Czy zna ktos jakis sposob rozwiazania dla takiego przypadku ?

1

wystarczy zrozumieć jedną prostą rzecz, strumień dowiaduje się o tym że ma EOF dopiero po nieudanej próbie wczytania, więc pętla:

while(!plik.eof()) { ... }

jest błędna, powinno być:

while(true)
  {
   //tu próba wczytania
   if(plik.eof()) break;
   //tu obróbka wczytanego
  }
0

W tym momencie jedynie przerywam petle mi chodzi o to aby wczytac ten znak i pozniej go odszyfrowac

0

Kod wczytywania wyglada nastepujaco

#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;

int main()
{

    char *key = new char[17];
    cout<<"Podaj klucz max 16 znakow"<<endl;
    cin.getline(key,17);

    ofstream O1("D://filekey.txt");
    if( O1.good() == true )
    {
        O1.write(key,17);
        O1.close();
    }

    char *plaintext = new char[1024];
    cout<<"Podaj tekst do zaszyfrowania"<<endl;
    cin.getline(plaintext,1024);

    ofstream O2("D://fileplaintext.txt");
    if( O2.good() == true )
    {
        O2.write(plaintext,1024);
        O2.close();
    }

    char *cyphertext = new char[1024];
    float X[1024];
    float x[1024];
    float Xnew = 0;
    int Xs = 0;
    int N = 0;
    int Ns = 0;
    int seed = 0;

    for(int counter=0;counter<strlen(key);counter++)
    {
        Xs = Xs ^ key[counter];
        Ns = Ns + key[counter];
        seed = seed + key[counter];
    }

    srand(seed);
    
    X[0] = (float)Xs/256;
    Ns = Ns % 256;
    int r;

    float Y[1024];
    Y[0] = 0;
    int a = 16;
    int c = 7;
    int m = 81;
    float Lambda[1024];
    
    int i=0;
    int l = strlen(plaintext);
    cout<<l<<endl;
    for(i=0;i<l;i++)
    {
        r = rand() % strlen(key);
        X[i+1] = fmodf( (X[0] + ((float)key[r] / 256)) , 1.0);
        N = Ns + key[r]; 
        Lambda[i]  = fmodf((a * Y[i] + c), m) / 200 + 3.57;
        Y[i+1] = fmodf((a * Y[i] + c), m);
        x[i] = X[i];
        
        for(int j=0;j<N;j++)
        {
            x[j+1] = Lambda[i] * x[j] * (1 - x[j]);
        }
        
        Xnew = x[N];
        cyphertext[i] = (plaintext[i] + ((int)(floor(Xnew * 256)))) % 256;
       // if(cyphertext[i] == EOF)
         //   i--;
       // cout<<cyphertext[i]<<endl;
        Ns = cyphertext[i];
        X[0] = Xnew;     
        cout<<"i = ["<<i<<"] = "<<cyphertext[i]<<endl;
    }
   
    cyphertext[i] = '\0';
    
    ofstream O3("D://filecyphertext.txt");
    if( O3.good() == true )
    {
        O3.write(cyphertext,i);
        O3.close();
    }

    delete [] plaintext;
    delete [] cyphertext;
    delete [] key;

    system("pause");
}
1

Po zaszyfrowaniu powstają dane binarny, więc zapisywać i odczytywać musisz je w trybie binarnym.

ofstream plik(Nazwa,ios::out|ios::binary);
ifstream plik(Nazwa,ios::in|ios::binary);
0

Jednak to nie była kwestia wczytywania binarnego.
Sprawdzając debugerem natknąlem sie na kody 0, -1 i 26 po których dalsze szyfrowanie danych nie było możliwe.
Przekształciłem kod i działa jak należy, a mianowicie dodałem

char c = (plaintext[i] + ((int)(floor(Xnew * 256)))) % 256;

    if((c == 0) || (c == -1) || (c == 26))
    {
        i--;
    }
    else
    {
        cyphertext[i] = c;
        Ns = cyphertext[i];
        X[0] = Xnew;     
        cout<<"i = ["<<i<<"] = "<<cyphertext[i]<<" = "<<(int)cyphertext[i]<<endl;
    }

Jeszcze mam taki problem z wczytywaniem chciałbym zrobić warunek który ograniczałby wczytanie do rozmiaru tablicy tj. 1024 bajtów
Nie wiem co moge dodac do takiego fragmentu kodu

char *plaintext = new char[1024];
cout<<"Podaj tekst do zaszyfrowania"<<endl;
cin.getline(plaintext,strlen(plaintext));

Pomysl mialem taki

cout<<strlen(plaintext)<<endl; //zwraca 1039
if(strlen(plaintext) > 1023)
    plaintext[1024] = '\0';
cout<<strlen(plaintext)<<endl; //zwraca 1024

Ale przy operacji delete [] plaintext odpala mi sie wyzwalacz pisze cos o stosie wiec blad z pamiecia jakies sugestie ?

0

Przy wczytywaniu binarnym mam identyczny efekt jak przy wczytywaniu tekstowym z tym ze dane w pliku sa inaczej zapisane.
A co do getline to chce wczytac do 1024 bajtow tyle ile jest zapisanych w tablicy czyli strlen(plaintext) a wiecej niz 1023 ograniczyc do wczytania 1023 i dodania znaku '\0' na koniec

0

Zapis binarny tekst jawny:
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn

Apis binarny kod odszyfrowany :
nnnnnn<Rnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn!őnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn!nnnnnnnnn<2nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn<Cnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn<Ćnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn<ćnnnnnnnnnnnnnnn!-nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn<Ônnnnn!9nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn;Ónnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn

Kawalek kodu istotny przy szfrowaniu i deszyfrowaniu pomijanie znakow 0, -1 i 26
char c = (plaintext[i] + ((int)(floor(Xnew * 256)))) % 256;

    if((c == 0) || (c == -1) || (c == 26))
    {
    }
    else
   {
        cyphertext[i] = c;
        Ns = cyphertext[i];
        X[0] = Xnew;     
        cout<<"i = ["<<i<<"] = "<<cyphertext[i]<<" = "<<(int)cyphertext[i]<<endl;
   }
1

Wywal teraz te 0 -1 26

0

Po zdjęciu if((c == 0) || (c == -1) || (c == 26))
Wartości zaszyfrowane + odpowiendnik ASCII

i = [970] = @ = 64
i = [971] = Ć = -58
i = [972] = 9 = 57
i = [973] = < = 60
i = [974] = ± = -79
i = [975] = n = 110
i = [976] = D = 68
i = [977] = 5 = 53
i = [978] = â = -30
i = [979] = = 0
i = [980] = Š = -118
i = [981] = n = 110
i = [982] = § = -89
i = [983] = = 30
i = [984] = Q = 81
i = [985] = 0 = 48
i = [986] = ° = -80
i = [987] = = = 61
i = [988] = ě = -20
i = [989] = 9 = 57
i = [990] = y = 121
i = [991] = – = -106
i = [992] = n = 110
i = [993] = 7 = 55
i = [994] = ˛ = -78
i = [995] = n = 110
i = [996] = % = 37
i = [997] = â = -30
i = [998] = # = 35
i = [999] = í = -19
i = [1000] = Ç = -57
i = [1001] = n = 110
i = [1002] = c = 99
i = [1003] = E = 69
i = [1004] = = 23
i = [1005] = đ = -16
i = [1006] = ´ = -76
i = [1007] = G = 71
i = [1008] = = 8
i = [1009] = # = 35
i = [1010] = d = 100
i = [1011] = 1 = 49
i = [1012] = = 31
i = [1013] = ő = -11
i = [1014] = ¬ = -84
i = [1015] = Â = -62
i = [1016] = n = 110
i = [1017] = 8 = 56
i = [1018] = N = 78
= 131019] =
i = [1020] = 7 = 55
i = [1021] = ˇ = -95
i = [1022] = n = 110

i = 1023
1023
979

3 ostatnie wartości :

cout<<"i = "<<i<<endl;
cout<<strlen(plaintext)<<endl;
cout<<strlen(cyphertext)<<endl;

Jak widać szyfrowane są wszystkie znaki i ta są zapisywane do pliki ale cyphertext jest zakończony na pozycji 979 a nie chcialbym aby tak bylo.

Deszyfracja
Tekst odszyfrowany
i = [950] = n = 110
i = [951] = n = 110
i = [952] = n = 110
i = [953] = n = 110
i = [954] = n = 110
i = [955] = n = 110
i = [956] = n = 110
i = [957] = n = 110
i = [958] = n = 110
i = [959] = n = 110
i = [960] = n = 110
i = [961] = n = 110
i = [962] = n = 110
i = [963] = n = 110
i = [964] = n = 110
i = [965] = n = 110
i = [966] = n = 110
i = [967] = n = 110
i = [968] = n = 110
i = [969] = n = 110
i = [970] = n = 110
i = [971] = n = 110
i = [972] = n = 110
i = [973] = n = 110
i = [974] = n = 110
i = [975] = n = 110
i = [976] = n = 110
i = [977] = n = 110
i = [978] = n = 110
979
979
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnn
979

Tekst jawny
1023
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
Niepoprawny tekst
Aby kontynuować, naciśnij dowolny klawisz . . .

Może jakos inaczej wczytac niz tym sposobem ?

ifstream I2("D://filecyphertext.tmp",ios::binary);


while(!I2.eof())
{

    I2.get(cyphertext[ii]);
    ii++;
    if(I2.eof())
        ii--;
}
cout<<ii<<endl;

cyphertext[ii] = '\0';
cout<<cyphertext<<endl;
1

Nie możesz użyć strlen dla zaszyfrowanego tekstu, bo może zawierać znaki '\0'.

ifstream I2("D://filecyphertext.tmp",ios::binary);
I2.seekg(0,ios::end); // na koniec pliku
int size=I2.tellg(); // numer pozycji = rozmiar pliku
char *cyphertext=new char[size]; // odpowiedni bufor
I2.seekg(0,ios::beg); // na początek pliku
I2.read(cyphertext,size); // wczytaj całość
I2.close();
cout<<"wczytano "<<size<<" znaków"<<endl;
//cyphertext[size] = '\0'; // nic to nie da, i tak strlen nie da się uzyć
//cout<<cyphertext<<endl; // to też nie zadziała bo się kończy na pierwszym zerze
0

czego użyć w takiej sytuacji ?

0

To było to czego potrzebowałem teraz wszystko działa poprawnie z zapisem binarnym do plików txt. Bardzo dziękuje za pomoc o każdej porze dnia i nocy, ciesze się że są takie osoby które mogą pomóc. Jeszcze raz dziękuje i pozdrawiam :)

0

Witam jak moge zmienic alokacje pamieci na dynamiczna w tablicy *x, aby kod działał poprawnie ?

char *ciphertxt = new char[size + 1];
float *X = new float[size+1];
  • float x[1024];**
    float Xnew = 0;
    int Xs = 0;
    int N = 0;
    int Ns = 0;
    int seed = 0;
for(int counter=0;counter<strlen(key);counter++)
{
    Xs = Xs ^ key[counter];
    Ns = Ns + key[counter];
    seed = seed + key[counter];
}

srand(seed);

X[0] = (float)Xs / 256;
Ns = Ns % 256;
int r;

float *Y = new float[size+1];
Y[0] = 0;
int a = 16;
int c = 7;
int m = 81;
float *Lambda = new float[size];

int i=0;
for(i=0;i<size;i++)
{
    r = rand() % strlen(key);
    X[i+1] = fmodf( (X[0] + ((float)key[r] / 256)) , 1.0);
    N = Ns + key[r]; 
    Lambda[i]  = fmodf((a * Y[i] + c), m) / 200 + 3.57;
    Y[i+1] = fmodf((a * Y[i] + c), m);
    
    x[i] = X[i];//x -> size
    
    for(int j=0;j<N;j++)
    {      
        x[j+1] = Lambda[i] * x[j] * (1 - x[j]); //x -> N
        cout<<"x["<<j+1<<"] = "<<x[j+1]<<endl;
    }     
    Xnew = x[N];  


    ciphertxt[i] = (plaintxt[i] + ((int)(floor(Xnew * 256)))) % 256;
    Ns = ciphertxt[i];
    X[0] = Xnew;     
    //cout<<"i = ["<<i<<"] = "<<ciphertxt[i]<<" = "<<(int)ciphertxt[i]<<endl;      
}
1

Linijkę wyżej przecież masz, nie potrafisz zrobić analogicznie?

Zacznij używać <code class="cpp">. Nie nazywaj zmiennych x, X, N itp, bo nic z tego nie wiadomo.

0

właśnie o to chodzi że analogicznie nie wychodzi :(

0

Nie szyfruje tekstu i sa bledy przy zwalnianiu pamieci nie mam pojecia jak to naprawic

     
#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;

int main()
{
    char *key;
    int size;
  
    ifstream I1("Debug/key.txt", ios::binary);
    if( I1.good() == true )
    {
        I1.seekg(0, ios::end); // na koniec pliku
        size = I1.tellg(); // numer pozycji = rozmiar pliku
        if(size == 0)
        {
            cout<<"Plik key.txt jest pusty"<<endl<<"Prosze wypelnic plik key.txt"<<endl;
            system("pause");
            return 0;
        }
        else if(size > 16)
        {
            cout<<"Plik key.txt zawiera powyzej 16 znakow !"<<endl<<"Prosze ograniczyc plik key.txt do 16 znakow"<<endl;
            system("pause");
            return 0;
        }
        cout<<size<<endl;
        key = new char[size+1]; // odpowiedni bufor
        I1.seekg(0, ios::beg); // na początek pliku
        I1.read(key, size); // wczytaj całość
        I1.close();
    }
    else
    {
        cout<<"Brak pliku o nazwie key.txt"<<endl<<"Utworz plik o nazwie key.txt"<<endl;
        system("pause");
        return 0;
    }  
    cout<<"wczytano "<<size<<" znakow z pliku key.txt"<<endl;
    key[size] = '\0';
    cout<<key<<endl;
    
    char *plaintxt;
 
    ifstream I2("Debug/plaintxt.txt", ios::binary);
    if( I2.good() == true )
    {
        I2.seekg(0, ios::end); // na koniec pliku
        size = I2.tellg(); // numer pozycji = rozmiar pliku
        if(size == 0)
        {
            cout<<"Plik plaintxt.txt jest pusty"<<endl<<"Prosze wypelnic plik plaintxt.txt"<<endl;
            system("pause");
            return 0;
        }
        else if(size > 1024)
        {
            cout<<"Plik plaintxt.txt zawiera powyzej 1kB !"<<endl<<"Prosze zmniejszyc rozmiar pliku plaintxt.txt"<<endl;
            system("pause");
            return 0;
        }
        plaintxt = new char[size + 1]; // odpowiedni bufor
        I2.seekg(0, ios::beg); // na początek pliku
        I2.read(plaintxt, size); // wczytaj całość
        I2.close();
    }
    else
    {
        cout<<"Brak pliku o nazwie plaintxt.txt"<<endl<<"Utworz plik o nazwie plaintxt.txt"<<endl;
        system("pause");
        return 0;
    }  
    cout<<"wczytano "<<size<<" znakow z pliku plaintxt.txt"<<endl;
    plaintxt[size] = '\0';
    cout<<plaintxt<<endl;

    char *ciphertxt = new char[size + 1];
    float *X = new float[size+1];
    float *x = new float[size+1];
    float Xnew = 0;
    int Xs = 0;
    int N = 0;
    int Ns = 0;
    int seed = 0;

    for(int counter=0;counter<strlen(key);counter++)
    {
        Xs = Xs ^ key[counter];
        Ns = Ns + key[counter];
        seed = seed + key[counter];
    }

    srand(seed);
    
    X[0] = (float)Xs / 256;
    Ns = Ns % 256;
    int r;

    float *Y = new float[size+1];
    Y[0] = 0;
    int a = 16;
    int c = 7;
    int m = 81;
    float *Lambda = new float[size];

    int i=0;
    for(i=0;i<size;i++)
    {
        r = rand() % strlen(key);
        X[i+1] = fmodf( (X[0] + ((float)key[r] / 256)) , 1.0);
        N = Ns + key[r]; 
        Lambda[i]  = fmodf((a * Y[i] + c), m) / 200 + 3.57;
        Y[i+1] = fmodf((a * Y[i] + c), m);
       /* 
        x = new float[N+1];
        for(int l=i; l!=-1; l--)
            x[l] = X[l];
        x[i] = X[i];//x -> size
        */
        for(int j=0;j<N;j++)
        {      
            x[j+1] = Lambda[i] * x[j] * (1 - x[j]); //x -> N
            cout<<"x["<<j+1<<"] = "<<x[j+1]<<endl;
        }     
        Xnew = x[N];  
        //delete [] x;

        ciphertxt[i] = (plaintxt[i] + ((int)(floor(Xnew * 256)))) % 256;
        Ns = ciphertxt[i];
        X[0] = Xnew;     
        //cout<<"i = ["<<i<<"] = "<<ciphertxt[i]<<" = "<<(int)ciphertxt[i]<<endl;      
    }
    ciphertxt[i] = '\0';
    cout<<ciphertxt<<endl;

    
    ofstream O1("Debug/encryptedplaintxt.txt", ios::binary);
    if( O1.good() == true )
    {
        O1.write(ciphertxt, size);
        O1.close();   
	}

  delete [] Y;
  delete [] x;  
  delete [] key;
  delete [] plaintxt;
  delete [] ciphertxt;
  delete [] X;
  delete [] Lambda;
  
  

   system("pause");

   return 0;
}


1

Przydzielasz pamięć nie zawsze, zaś zwalniasz zawsze i to jest problem.

char *plaintext=0;
...
if(plaintext) delete[] plaintext;
0

Przydzielam pamiec tylko w momencie istnieje klucz i plaintxt, ale zauważ że gdy nie ma tych składników to kończe program i nie alokuje pamięci.
Coś jest nie tak raczej z szyfrowaniem, bo do pliku cyphertxt.txt wpisuje mi nie zmienioną zawartość czyli plaintxt jakby wcale nie szyfrował.

0

Teraz mam problem z zapisem znaków sterujących do pliku. Czy jest jakiś sposób na zapisanie tych znaków do pliku .txt bo gdy je zapisuje zapisuja mi sie jako prostokąty po czym nie moge ich skopiowac do kolejnego pliku i nie wiem co jest grane ?

0

Wszytko dobrze ale chodzi o to żeby tekst dobrze zaszyfrowac nie w postaci prostokatow nie wiem czy jest to mozliwe ???

1
  1. Ustalasz jakie znaki są legalne np a..z A..Z
  2. Przed szyfrowaniem/deszyfrowaniem sprawdzasz czy wszystkie znaki są z tego zakresu, jak nie to - nie da się.
  3. Przed szyfrowaniem/deszyfrowaniem zamieniasz znak na jego pozycje na liście legalnych
  4. zamiast 256 w twoim kodzie używasz LiczbaLegalnychZnaków
  5. Po szyfrowaniu/deszyfrowaniu wyjdą ci pozycje znaków, zamieniasz pozycje na liście legalnych na znak.
0

gdz dam tak : zamiast 256 w twoim kodzie używasz LiczbaLegalnychZnaków to zakres bedzie od 0 do LiczbaLegalnychZnaków wiec znaki sterujace zalapia sie czy sie myle ?

1
#include <iostream>
#include <cstring>
using namespace std;

const char LegalSign[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ .,!?abcdefghijklmnopqrtsuvwxyz";

bool encode(char *text)
  {
   for(;*text;++text)
     {
      char *p=strchr(LegalSign,*text);
      if(!p) return false;
      *text=p-LegalSign;
     }
   return true;
  }

bool decode(char *text,unsigned len)
  {
   for(int max=sizeof(LegalSign);len--;++text)
     {
      if((0>*text)||(*text>=max)) return false;
      *text=LegalSign[(int)*text];
     }
   return true;
  }

int main()
  {
   char text[100];
   strcpy(text,"Ala ma kota. ZazA");
   int len=strlen(text);
   if(encode(text))
     {
      for(int i=0;i<len;++i) cout<<(int)text[i]<<' ';
      cout<<endl;
      if(decode(text,len))
        {
         cout<<text<<endl;
        }
      else cout<<"decode error"<<endl;
     }
   else cout<<"encode error"<<endl;
   cin.sync();
   cin.get();
   return 0;
  }
0

Ostatnie pytanie odnośnie alokacji

#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;

int main()
{
    char *key;
    int size;

    ifstream I1("../Debug/key.txt", ios::binary);
    if( I1.good() == true )
    {
        I1.seekg(0, ios::end);
        size = I1.tellg();
        if(size == 0)
        {
            cout<<"Plik key.txt jest pusty"<<endl<<"Prosze wypelnic plik key.txt"<<endl;
            system("pause");
            return 0;
        }
        else if(size > 16)
        {
            cout<<"Plik key.txt zawiera powyzej 16 znakow !"<<endl<<"Prosze ograniczyc plik key.txt do 16 znakow"<<endl;
            system("pause");
            return 0;
        }
        key = new char[size+1];
        I1.seekg(0, ios::beg);
        I1.read(key, size);
        I1.close();
    }
    else
    {
        cout<<"Brak pliku o nazwie key.txt"<<endl<<"Utworz plik o nazwie key.txt"<<endl;
        system("pause");
        return 0;
    }  
    key[size] = '\0';

    char *plaintxt;
    ifstream I2("../Debug/plaintxt.txt", ios::binary);
    if( I2.good() == true )
    {
        I2.seekg(0, ios::end);
        size = I2.tellg();
        if(size == 0)
        {
            cout<<"Plik plaintxt.txt jest pusty"<<endl<<"Prosze wypelnic plik plaintxt.txt"<<endl;
            system("pause");
            return 0;
        }
        else if(size > 1024)
        {
            cout<<"Plik plaintxt.txt zawiera powyzej 1kB !"<<endl<<"Prosze zmniejszyc rozmiar pliku plaintxt.txt"<<endl;
            system("pause");
            return 0;
        }
        plaintxt = new char[size+1];
        I2.seekg(0, ios::beg);
        I2.read(plaintxt, size);
        I2.close();
    }
    else
    {
        cout<<"Brak pliku o nazwie plaintxt.txt"<<endl<<"Utworz plik o nazwie plaintxt.txt"<<endl;
        system("pause");
        return 0;
    }  
    plaintxt[size] = '\0';

    char *ciphertxt = new char[size+1];
    float *X = new float[size+1];
    float Xnew = 0;
    int Xs = 0;
    int N = 0;
    int Ns = 0;
    int seed = 0;

    for(int counter=0;counter<strlen(key);counter++)
    {
        Xs = Xs ^ key[counter];
        Ns = Ns + key[counter];
        seed = seed + key[counter];
    }

    srand(seed);

    X[0] = (float)Xs / 256;
    Ns = Ns % 256;
    int r;

    float *Y = new float[size+1];
    Y[0] = 0;
    int a = 16;
    int c = 7;
    int m = 81;
    float *Lambda = new float[size+1];
//    float *x = new float[size+1];
    float x[1024];
    for(int i=0;i<size;i++)
    {
        r = rand() % strlen(key);
        X[i+1] = fmodf( (X[0] + ((float)key[r] / 256)) , 1.0);
        N = Ns + key[r]; 
        Lambda[i]  = fmodf((a * Y[i] + c), m) / 200 + 3.57;
        Y[i+1] = fmodf((a * Y[i] + c), m);
        x[i] = X[i];

        for(int j=0;j<N;j++)
            x[j+1] = Lambda[i] * x[j] * (1 - x[j]);

        Xnew = x[N];         

        ciphertxt[i] = (plaintxt[i] + ((int)(floor(Xnew * 256)))) % 256;
        N = ciphertxt[i];
        X[0] = Xnew;          
    }

    ciphertxt[size] = '\0';

    ofstream O1("../Debug/encryptedplaintxt.txt", ios::binary);
    if( O1.good() == true )
    {
        O1.write(ciphertxt, size);
        O1.close();   
    }

    cout<<"Zaszyfrowano poprawnie tekst do pliku encryptedplaintxt.txt"<<endl;
   // delete [] x;
    delete [] Y;  
    delete [] key;
    delete [] plaintxt;
    delete [] ciphertxt;
    delete [] X;
    delete [] Lambda;
  
    system("pause");
    return 0;
}

wszystko działa poprawnie ale gdy chce odkomentowac program czasem sie sypie czasem nie dlaczego jest jakas regula ?

1

Ja ci już o tym mówiłem ale ty to zignorowałeś:

char *plaintxt; // tu masz śmieć
    if(...) // tu nie koniecznie wejdzie
    {
...
        plaintxt = new char[size+1];
...
    }
...
    delete [] plaintxt; // zwalniasz pseudo losowy adres

Pozbądź się wszystkich takich błędów.

0

Ok a co do prostokątów które czasami się ukazują po zaszyfrowaniu to czy można jakoś może zmienić sposób kodowania aby nie były wyświetlane prostokąty ?
I jak próbuje to przenieść na C# to to przy pliku 224 bajtów rozmiar zaszyfrowanego pliku wynosi 318. Widzę że przy szyfrowaniu tablica ma odpowiedni rozmiar więc widać że chodzi o zapis do pliku a zapisuje to tak
StreamWriter zapis = new StreamWriter("encryptedtxt.txt");
zapis.Write(ciphertxt);

0

Wczytuje do tablicy bajtów plaintxt zajmuje 224 tyle ile plik i klucz 15 tyle ile plik, ciphertxt 225 a plik ciphertxt.txt 319 przy rzutowaniu na char a bez rzutowania 548 nie rozumiem dlaczego i nie wiem jak to przerobic zeby byl stosunek 1 : 1 ?
A co do krzaczków to wygląda to niekiedy tak : #Ô)”n`‚ W¸pÉbSłmOç‡oQ©lPid a niekiedy caly tekst zaszyfrowany tak :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace PareekCSharp1
{
    class Program
    {

        static void Main(string[] args)
        {
            long size;
            byte[] key = File.ReadAllBytes("key.txt");
byte[] plaintxt = File.ReadAllBytes("plaintxt.txt");
            size = plaintxt.Length;
byte[] ciphertxt = new byte[size + 1];

            double[] X = new double[size + 1];
            double Xnew = 0;
            int Xs = 0;
            int N = 0;
            int Ns = 0;
            int seed = 0;


            for (int counter = 0; counter < key.Length; counter++)
            {
                Xs = Xs ^ key[counter];
                Ns = Ns + key[counter];
                seed = seed + key[counter];
            }

            Random rand = new Random(seed);

            X[0] = (double)Xs / 256;
            Ns = Ns % 256;
            int r;

            double[] Y = new double[size + 1];
            Y[0] = 0;
            int a = 16;
            int c = 7;
            int m = 81;
            double[] Lambda = new double[size + 1];
            double[] x = new double[1024];

            for (int i = 0; i < plaintxt.Length; i++)
            {
                r = rand.Next() % key.Length;
                X[i + 1] = (X[0] + ((double)key[r] / 256)) % 1.0;
                N = Ns + key[r];
                Lambda[i] = ((a * Y[i] + c) % m) / 200 + 3.57;
                Y[i + 1] = (a * Y[i] + c) % m;
                x[i] = X[i];
                for (int j = 0; j < N; j++)
                    x[j + 1] = Lambda[i] * x[j] * (1 - x[j]);

                Xnew = x[N];
                int aaa = (plaintxt[i] + ((int)(Math.Floor(Xnew * 256)))) % 256;
                ciphertxt[i] = (byte)aaa;
                Console.WriteLine(ciphertxt[i]);
                N = (int)ciphertxt[i];
                Console.WriteLine(N);
                X[0] = Xnew;
            }

            StreamWriter zapis = new StreamWriter("encryptedtxt.txt");
            int jjj = 0;
            while (jjj != 225)
            {
                zapis.Write((char)ciphertxt[jjj]);
                jjj++;
            }
            zapis.Close();

        }
    }
}
0

Przy implementacji w C# natknąłem się na następujący problem tj. przy losowaniu w chciałbym aby wyszły takie same wartości r z tym że zwraca mi te wartości różne. Wszystkie pozostałe wartości są identyczne. Jak doprowadzić do zwrócenia identycznych wartości ?

 
   srand(seed);
    for(int i=0;i<size;i++)
    {
        r = rand() % strlen(key);
    }
 
Random rand = new Random(seed);
            for (int i = 0; i < (int)plaintxt.Length; i++)
            {
                r = rand.Next() % key.Length;
            }

1

Masz na myśli że C nie daje te same wartości co C#?

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