2015-12-12 4 views
1

Я следил за учебником на веб-сайте stephan-brumme для шифрования XOR (к сожалению, я не могу включить URL, потому что у меня недостаточно репутации). Я хочу сделать следующее: прочитать содержимое файла example.txt и расшифровать текст, который он включает. Например, это содержание example.txt:C++ XOR шифрование - проблема с расшифровкой

\xe7\xfb\xe0\xe0\xe7 

Это, когда расшифрованы с помощью пароля «пароль» должен вернуть «привет». Это код, который я получил:

#include <string> 
#include <iostream> 
#include <fstream> 

using namespace std; 

std::string decode(const std::string& input) 
{ 
    const size_t passwordLength = 9; 
    static const char password[passwordLength] = "password"; 
    std::string result = input; 
    for (size_t i = 0; i < input.length(); i++) 
    result[i] ^= ~password[i % passwordLength]; 
    return result; 
} 

int main(int argc, char* argv[]) 
{ 
    string line; 
    ifstream myfile ("example.txt"); 
    if (myfile.is_open()) 
    { 
    while (getline (myfile,line)) 
    { 
     cout << decode(line); 
    } 
    myfile.close(); 
    } 

    return 0; 
} 

И это результат работы приложения: click for image

Как вы можете видеть, дешифровка не удалась. Теперь, если я делаю это так, то не читает .txt, а непосредственно расшифровывает текст, например:

cout << decode("\xe7\xfb\xe0\xe0\xe7"); 

Он отлично работает: click for image

Что я здесь делаю неправильно?

Большое спасибо заранее! :)

+0

наиболее вероятный источник является содержанием example.txt. Помните, что вывод XOR находится в двоичном формате, что означает, что example.txt должен быть UTF-8. Для согласованности всегда используйте ключ и ввод того же типа [Ex: char или widechar (utf-8)] – Nandu

+0

example.txt - UTF-8. Спасибо, что пытались помочь! – MrWhite

+0

может включать изображение, отображающее содержимое файла? – Nandu

ответ

1

Символ XOR одним и тем же символом равен нулю, поэтому результат может включать в себя ноль. std::string не нравится, потому что нуль завершает строку.

Вы также можете использовать std::vector<char> вместо std::string для фактического кодирования/декодирования. Вам нужно будет изменить функцию decode для обработки vector<char>

И прочитайте/напишите файл в двоичном формате.

Edit: Использование std::string только и std::string decode(const std::string& input)

int main() 
{ 
    std::string line = "hello"; 

    { 
     line = decode(line); 
     std::ofstream myfile("example.txt", std::ios::binary); 
     myfile.write(line.data(), line.size()); 

     //Edit 2 ************* 
     //std::cout << std::hex; 
     //for (char c : line) 
     // std::cout << "\\x" << (0xff & c); 
     //************* 
     //This will make sure width is always 2 
     //For example, it will print "\x01\x02" instead of "\x1\x2" 
     std::cout << std::hex << std::setfill('0'); 
     for (char c : line) 
      std::cout << "\\x" << std::setw(2) << (0xff & c); 
     std::cout << std::endl; 
    } 

    { 
     std::ifstream myfile("example.txt", std::ios::binary | std::ios::ate); 
     int filesize = (int)myfile.tellg(); 
     line.resize(filesize); 
     myfile.seekg(0); 
     myfile.read(&line[0], filesize); 
     line = decode(line); 
     std::cout << line << std::endl; 
    } 

    return 0; 
} 
+0

'std :: string' может содержать символы NUL только в порядке (строки C, которые имеют проблемы с NUL), поэтому нет необходимости использовать' vector'. Проблема (которую вы решаете) заключается в том, что 'getline' не может иметь дело с NUL, плюс, если новые строки зашифрованы,' getline' не сможет их найти, поэтому вам нужно использовать двоичные чтения. –

+0

Это прекрасно работает, но мне нужно, чтобы «привет» был зашифрован с удобочитаемым способом. Я имею в виду, мне нужно, чтобы это было как \ xe7 \ xfb \ xe0 \ xe0 \ xe7, а не так: http://i.imgur.com/tne1I7T.png Возможно ли это? Большое спасибо! – MrWhite

+0

@ChrisDodd, вы правы. Иногда 'std :: string' заканчивается, например, когда вы видите« abc \», я обычно избегаю этого, когда задействован нуль. Но в этом случае все должно быть хорошо. Я отредактирую ответ, чтобы показать просто 'std :: string' –

1

Уверен, что пример.txt содержит символы '\', 'x', 'e', ​​'7' и т. Д. Вы должны прочитать их, обработать все обратные слэши, а затем подать его на декодирования.

\ xe7 - общий способ представления символа с шестнадцатеричным значением E7. (Скорее всего, это единственный символ «ç» в зависимости от вашего набора символов). Если вы хотите сохранить (зашифрованный) читаемый текст, я предлагаю сбросить \ x и иметь файл с такими строками, как «e7fbe0e0e7». Затем - прочитайте каждую строку в строке. - Преобразование каждой пары символов из шестнадцатеричного числа в целое число и сохранение результата в символе. - Сохраните этот символ в строке. - Затем xor расшифровывает строку.

В качестве альтернативы, убедитесь, что файл содержит фактические двоичные символы, в которых вы нуждаетесь.

Также обратите внимание на то, что вы XOR-ing с завершающим нулевым байтом пароля. Вы хотели сделать это?

+0

Я все для отрицательных ответов - но помогите мне улучшить; скажите мне, что * плохой о моем ответе. –

+0

Да, он включает в себя эти символы. Извините, я не понимаю, что вы подразумеваете под «обработкой всех обратных слэшей, а затем кормить их для декодирования». Вы можете быть более конкретным, пожалуйста? Большое спасибо за помощь! – MrWhite

+0

\ xe7 - общий способ представления символа * * с шестнадцатеричным значением E7. (Скорее всего, это единственный символ «ç» в зависимости от вашего набора символов). Если вы хотите сохранить (зашифрованный) читаемый текст, я предлагаю удалить \ x и иметь файл, содержащий строки типа «e7fbe0e0e7» –

Смежные вопросы