2011-08-08 3 views
0

자, C + +를 배우려고 노력하고있어 암호화/해독 프로그램을 만들려고 결정했습니다. 아이디어는 파일을 열고 암호에 따라 비트를 편집하는 것입니다. 내 코드에 문제가 있고 중단 점을 사용하여 파일을 열 때 오류가 발생한다는 것을 알았습니다 (주()에 약 1/3 정도). Visual C++에서는 힙이 손상되었다고 말하며 이유는 무엇인지 알 수 없습니다. 어떤 도움이라도 대단히 감사하겠습니다.알 수없는 C++ 힙 손상 InDev 비트 기반 암호화 프로그램, 새로운 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; 
} 
+1

어때요? 당신이 말한 오류가'file.open (...........)'호출에서 발생하기 때문에, 왜 파일을 먼저 열려고 시도하지 않고 파일을 읽었을 수 있습니까? 일단 당신이 알아 낸 것이 당신은 암호화/해독 물건으로 앞으로 갈 수 있습니다. 그리고 만약'if (Obj = 1) '를 할당하는 대신'if (Obj == 1)'을 사용하여 값을 검사하도록 swap 메소드를 수정하십시오. – Purnima

답변

0

문제의 원인인지 확실하지는 않지만 읽는 파일에 직접 쓰는 것은 현명한 방법이 아닙니다. 완료되면 임시 파일에 쓰고 파일 이름을 바꿉니다. 다음과 같은 코드가 -method 당신의 conversion()에서

1

: convert의 길이가 8보다 작 으면

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

을, 당신은 루프 내부의 password -array 외부에서 작성됩니다.

일반적으로 힙 손상은 한 번에 감지되지 않으므로 파일을 열 때까지 오류가 발생하지 않습니다.

+0

이것은 벡터가 아닌 배열을 사용하는 좋은 이유입니다. 많은 구현에서 벡터는 오류가 발생했을 때 오류를 줄 수 있지만 배열을 사용하면 나중에 오류가 있음을 알게되므로 분명히 디버깅을 어렵게 만듭니다. – john