Newsgroup: it.comp.lang.c++
Titolo: Problema con la gestione stringhe e qualche xor...

Ciao a tutti,
è da un poco che mi sto avvicinando al c++, e dopo aver studiato classi puntatori e via dicendo, sto facendo un pò di pratica con la gestione delle stringhe.
Premetto che per ora sto lavorando solo con le classi ofstream e ifstream. 
Vi espongo il mio problema:
devo leggere carattere per carattere tutti i dati che si trovano in un file fino ad arrivare al termine del file stesso (non mi devo quindi bloccare al primo
'\0' o '\n') e riportarli in un secondo file creato ex novo, previo xor di ogni carattere letto con una chiave cifrata dichiarata all'inizio.
Così che il programma se ha in entrata il file cifrato, lo restituirà decifrato, e se il file è in chiaro lo cifrerà.
Il mio problema sta che nel prog che stavo abbozzando quando leggeva dal file cifrato, non restituiva sempre il testo in chiaro giusto ma si bloccava prima se
incontrava dei caratteri di fine riga o simili... come posso ovviare a ciò e fargli leggere ugualmente quei caratteri e gestirli come fossero altri caratteri
normali?
Vi posto di seguito il sorgente (sorvolate sulla efficacia della protezione, l'ho solo fatto per esercizio, se riesco a risolvere questo prob si può modificare
nel più sicuro one time pad), vi dico anche che ho utilizzato la funzione tellg() ed il parametro ios::ate per avere la dimensione in byte del file, ma come vi
ho detto all'inizio, ho iniziato da poco ad avvicinarmi al c++, per cui il codice probabilmente non è per niente ottimizzato nè ottimale per lo scopo...btw,
eccovelo:
#include <iostream.h>
#include <fstream.h>
int main()
{
char inFile[20];
char outFile[20];
char charRead,d;
char *cypher = "questalachiavechevogliousare";
int maxsize(strlen(cypher));
maxsize--;
int i=0,out;
long j=0;
cout << "Dimmi il nome del file da cifrare/decifrare: " << endl;
cin >> inFile;
cout << "\nDimmi il nome che vuoi dare al file cifrato/decifrato: " << endl;
cin >> outFile;
ifstream inRead1(inFile, ios::in|ios::ate);
long size = inRead1.tellg();
ifstream inRead(inFile);
ofstream outWrite(outFile, ios::out);
while (j<size)
{
inRead.get(charRead);
out = (int)charRead^((int)cypher[i]);
outWrite.put((char)out);
if (i==maxsize) {
i=0;
}
i++;
j++;
}
return 0;
}

Ciao, io ho un programmino in c che fa la stessa cosa ma forse a te serviva
esclusivamente in c++? Bè, io te lo posto, se non ti serve amen.
#include <stdio.h>
void main()
{
 FILE *file,*fout,*fdecript;
 char carattere;
 char passwd[20];
 char key=0;
 int i;
 printf("Inserire password: ");
 scanf("%s",passwd);
 for(i=0;i<20;i++) key+=passwd[i]; //calcola la chiave in qualche modo...
    /*criptazione*/
    file=fopen("c:\\test.txt","r");
 fout=fopen("c:\\out.txt","w");
 while(fscanf(file,"%c",&carattere)!=EOF)
 {
  carattere+=key;
  fprintf(fout,"%c",carattere);
 }
 fclose(file);
 fclose(fout);
    /*decriptazione*/
 fout=fopen("c:\\out.txt","r");
 fdecript=fopen("c:\\decript.txt","w");
 while(fscanf(fout,"%c",&carattere)!=EOF)
 {
  carattere-=key;
  fprintf(fdecript,"%c",carattere);
 }
 fclose(fout);
 fclose(fdecript);
}

Ti ringrazio per la risposta e per il prog. Il fatto è che quello che avevo scritto l'ho fatto giusto per esercizio sulle classi ifstream ed ofstream, volevo
perciò risolvere il prob esposto usando queste classi se possibile e capire dove sbaglio.
Terrò comunque il tuo programma per analizzarlo quando farò la classe stdin :)
Ciao!
Luigi


 [snip]
Il tuo programma non fa esattamente la stessa cosa, perché non usa lo xor
bensě l'overflow della somma.
Un programma come quello che voleva l'OP potrebbe essere questo (il testing
lo lascio ai lettori ;-))) ):
#include <iostream>
using namespace std;
void crypt_decrypt( const string& _filename_in, const string& _filename_out,
const string& _key ) {
   ifstream ifs( _filename_in.c_str(), ios::binary | ios::in );
   ofstream ofs( _filename_out.c_str(), ios::binary | ios::out );
   int keypos = 0;
   while( ! ifs.eof() ) {
      char c;
      ifs.read( &c, 1 );
      c ~= key[ keypos++ ];
      if ( keypos == _key.size() ) keypos = 0;
   }
}
Esempio di uso:
    // Cifratura.
    crypt_decrypt( "testo.txt", "testo.enc", "secret" );
    // Decifratura
    crypt_decrypt( "testo.enc", "testo_decifrato.txt", "secret" );
Ciao!
Marco Spedaletti

 }
Ciao!
Marco Spedaletti

#include <iostream>
                   ^^^^^^
il compilatore borland mi da un errore se uso iostream così pur dichiarando di usare i namespace (che non conosco e mi andrò
a documentare per non tediarvi con inutili domande) per cui nel mio ho continuato ad usar iostream.h e fstream.h
Prima di postarti il codice così come l'ho riaggiustato volevo chiederti, tu hai dichiarato le string come constant, che mi cambia se le
lascio string e basta e/o perchè sarebbe meglio dichiararle come constant?
Grazie mille ancora, ciao!!
#include <iostream.h>
#include <fstream.h>
int main()
{
char charRead;
string inTxtFile, outTxtFile, cypher;
unsigned int i=0;
cout << "Digita la chiave: " << endl;
cin >> cypher;
cout << "Dimmi il nome del file da cifrare/decifrare: " << endl;
cin >> inTxtFile;
cout << "\nDimmi il nome che vuoi dare al file cifrato/decifrato: " << endl;
cin >> outTxtFile;
ifstream inFileRead(inTxtFile.c_str(), ios::binary | ios::in);
ofstream outFileWrite(outTxtFile.c_str(),  ios::binary | ios::out);
while (!inFileRead.eof())
{
inFileRead.read(&charRead,1);
charRead ^=cypher[i]^i;
outFileWrite.write(&charRead,1);
i++;
if (i==cypher.size()){i=0;}
}
return 0;
}

 lascio string e basta e/o perchč sarebbe meglio dichiararle come constant?
Io ho dichiarato costante i parametri della funzione (anzi, per la
precisione: riferimento a stringhe costanti). Questo mi garantisce che, se
un utilizzatore mi passa delle stringhe, esse:
1) non vengono copiate bit-a-bit sullo stack;
2) non vengono da me modificate.
Tutto questo aiuta ad ottimizzare i programmi (eviti di fare una copia in
piů) e alla correttezza (se avessi modificato non intenzionalmente il
parametro in ingresso, il compilatore me lo avrebbe segnalato e non avrebbe
proceduto oltre).
Ciao.
Marco Spedaletti

Ok perfetto, ora č chiaro :) 
Ciao!
