Witam, już kilka razy robiłem programy xor'ujące pliki, nigdy jednak jeszcze nie próbowałem tego w czystym C++ ( bibliotece standardowej ). Oto mój kod:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
class StrLoopIterator {
private:
std::string m_str;
std::string::iterator m_it;
public:
StrLoopIterator(std::string str) : m_str(str), m_it(m_str.begin()) {}
char next() {
char t = *m_it;
m_it++;
if (m_it >= m_str.end())
m_it = m_str.begin();
return t;
}
void reset() {
m_it = m_str.begin();
}
};
//-------------------------------------------------------------------------------
std::streampos getFileByteSize(std::string filename) {
std::ifstream bfile(filename);
if (!bfile.is_open())
return 0;
bfile.seekg(0, std::ios_base::end);
std::streampos size = bfile.tellg();
bfile.clear();
bfile.close();
return size;
}
//-------------------------------------------------------------------------------
void fileXOR(std::string filename, std::string key, std::streampos filesize) {
std::fstream file(filename, std::ios_base::out | std::ios_base::in | std::ios_base::binary);
if (!file.is_open())
throw "File not found";
StrLoopIterator keyit(key);
for (std::streampos i = 0; i < filesize; i+=1) {
char ch;
file.seekg(i);
file.read(&ch, sizeof ch);
file.seekg(i);
ch ^= keyit.next();
file.write(&ch, sizeof ch);
}
file.clear();
file.close();
}
//-------------------------------------------------------------------------------
int main() {
std::cout << "File name: ";
std::string filename;
std::cin >> filename;
std::cout << "Key: ";
std::string key;
std::cin >> key;
std::streampos filesize = getFileByteSize(filename);
try {
fileXOR(filename, key, filesize);
}
catch (char* str) {
std::cout << str << "\n";
}
std::cin.get();
std::cin.get();
}
I tu mam pytanie dotyczące efektywności tego co zrobiłem, tyczy się to oczywiście głównie samego odczytu i zapisu informacji do pliku:
StrLoopIterator keyit(key);
for (std::streampos i = 0; i < filesize; i+=1) {
char ch;
file.seekg(i);
file.read(&ch, sizeof ch);
file.seekg(i);
ch ^= keyit.next();
file.write(&ch, sizeof ch);
}
zapis i odczyt odbywa się w jednej pętli, bajt po bajcie. Dla małych plików jest ok, ale przetwarzanie zdjęć trwa nawet ponad minutę. Czy jest jakiś bardziej szybki i elegancki sposób w jaki mógłbym to zrealizować? Może pobierać większe bloki danych w zależności od pliku?
Pytanie krótkie, ale zawsze jak coś napiszę to zdaję sobie sprawę że to może być bardzo nieprofesjonalny kod i chcę znać ewentualne lepsze wyjścia z sytuacji ;)
Dziękuje za porady i pozdrawiam :)