неизвестное повреждение кучи в C ++ в программе шифрования на основе битов InDev, впервые в программировании на C ++ - PullRequest
0 голосов
/ 08 августа 2011

Хорошо, я пытался самостоятельно изучить C ++ и поэтому решил попробовать создать программу шифрования / дешифрования.Идея состоит в том, чтобы открыть файл и редактировать биты в соответствии с паролем.У меня возникли некоторые проблемы с моим кодом, и с помощью точек останова я обнаружил, что ошибка возникает, когда я открываю файл (он находится в main () примерно на треть пути вниз).Visual C ++ говорит мне, что куча стала поврежденной, и я не понимаю, почему.Любая помощь будет принята с благодарностью.

#include <iostream>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <fstream>
#include <sys/stat.h>
using namespace std;
unsigned char fileData[31];
bool *password;
int count(0), maxCount;

/*
* Programmer:       P7r0
* Program:          Encrypt/Decrypt
* Version:          InDev
* Date Released:    -
*
* Notes:
*   -
*/

struct bits{
    // Breaks each byte into its 8 bits
    unsigned int b1 : 1;
    unsigned int b2 : 1;
    unsigned int b3 : 1;
    unsigned int b4 : 1;
    unsigned int b5 : 1;
    unsigned int b6 : 1;
    unsigned int b7 : 1;
    unsigned int b8 : 1;
} ;

// Toggles the bits, ie if 1 make 0
int swap(int Obj){
    if (Obj = 1){return 0;}
    else if (Obj = 0){return 1;}
}

void conversion(string convert){
    // User password to a boolean array
    int ascii, loop, count, a, counter(0);
    const char *code;
    bool bin [ ] = {false,false,false,false,false,false,false,false};
    // Create an array for the booleans
    password = new bool [convert.length()];
    code = convert.c_str();
    for (loop = 0;loop < convert.length(); loop++){
        for (a = 0;a < 8;a++){bin[a] = false;}
        // Get the equivilent ASCII code
        ascii = int(code[loop]);
        while (ascii > 0){
            // Develop a tempory binary array with code based off of the ASCII values
            if (ascii >= 128){ascii -= 128;bin[0] = true;}
            else if (ascii >= 64){ascii -= 64;bin[1] = true;}
            else if (ascii >= 32){ascii -= 32;bin[2] = true;}
            else if (ascii >= 16){ascii -= 16;bin[3] = true;}
            else if (ascii >= 8){ascii -= 8;bin[4] = true;}
            else if (ascii >= 4){ascii -= 4;bin[5] = true;}
            else if (ascii >= 2){ascii -= 2;bin[6] = true;}
            else if (ascii >= 1){ascii -= 1;bin[7] = true;}
        }
        for (count = 0; count < 8; count++){
            // Move out of the tempory array into the main array for global use
            //cout << bin[count];
            password[counter] = bin[count];
            counter++;
        }
        //cout << ":\n";
    }
}

int encrypt(int loop){
    // Changes everything bit by bit in blocks of bytes the size of loop, typically 32
    int a, b, counter(0);
    bits bit;
    for (a = 0; a == loop; a++){
        bit = * (bits*)(&fileData[a]);
        cout << bit.b1 << "\t";
        for (b = 0; b == 7; b++){
            if (count = maxCount){count = 0;}
            if (password[count] = true){
                // If current password array is true then toggle current bit
                if (b = 0){bit.b1 = swap(bit.b1);}
                else if (b = 1){bit.b2 = swap(bit.b2);}
                else if (b = 2){bit.b3 = swap(bit.b3);}
                else if (b = 3){bit.b4 = swap(bit.b4);}
                else if (b = 4){bit.b5 = swap(bit.b5);}
                else if (b = 5){bit.b6 = swap(bit.b6);}
                else if (b = 6){bit.b7 = swap(bit.b7);}
                else if (b = 7){bit.b8 = swap(bit.b8);}
                count++;}
            else {count++;}
        }
        cout << counter;
        fileData[counter] = *(unsigned char*)(&bit);
        counter++;
    }
    return 0;
}

int main(){
    fstream file;
    char *remainder;
    int counter, size, temp, b(0), stackCount(0);
    long begin, end;
    string usrin, pass, pause, filedir;
    cout << "Please input password, must be one word\n";
    cin >> pass;
    maxCount = pass.length();
    conversion(pass);
    // Change password data stored at its location as to avoid unwanted detection of the password
    pass = "default";
    cout << "\nPlease input file path\n";
    cin >> filedir;
    //The error seems to be here
    file.open(filedir.c_str(),ios::in | ios::out | ios::binary);
    // Check that the file is open
    if (file.is_open()){
        cout << "Encrypting...\n";
        counter = 32;
        // Work out size (bytes) of the file
        begin = file.tellg();
        file.seekg(0,ios::end);
        end = file.tellg();
        file.seekg(0,ios::beg);
        b = file.tellg();
        size = end-begin;
        while((int)b <= size){
            // Had to typecast as the unsigned/signed mis-match was throwing compile errors
            file.read((char*)(&fileData),counter);
            encrypt(counter);
            if (size - b >= 32){
                file.write((char*)(&fileData),counter);
                b = file.tellg();
            } else if (size - b < 32 && size - b > 0) {
                remainder = new char [size - b];
                for (int a = 0; a != size - b; a++){remainder[a] = fileData[a];}
                file.write((char*)(remainder),size - b);
                // To cancel out of the while loop
                b += 1;
            } else if (size - b == 0){b += 1;}
        }
        file.close();
        cout << "\nEncrypted.\nPlease enter a letter to continue\n";
        cin >>  pause;
    // Prompt user if unable to open the file
    } else {cout << "Failed to open the file";}
    return 0;
}

Ответы [ 2 ]

1 голос
/ 08 августа 2011

В вашем conversion() -методе есть следующий код:

int counter(0);
// ...
password = new bool [convert.length()];
// ...
for (count = 0; count < 8; count++){
    password[counter] = bin[count];
    counter++;
}

Если длина convert меньше 8, вы будете писать вне массива password внутриloop.

Повреждение кучи обычно не обнаруживается сразу, поэтому вы не получите ошибку до открытия файла.

0 голосов
/ 08 августа 2011

Не уверен, что это является причиной вашей проблемы, но в любом случае неразумно писать прямо в файл, из которого вы читаете. Запишите во временный файл и переименуйте файлы, когда закончите.

...