1

Base2 ファイル データを Base64 に変換するこの小さなコンバーターを作成しました。結果の出力が正しくなく、その理由がわかりません。画像ファイルが入力として渡された場合、問題はさらに悪化します。発生してはならないランダムな NULL 文字 (0x00) が出力に挿入されます。出力には、Base64Table のサブセットのみが含まれている必要があります (コードを参照)。


入力:

人間は、その理性だけでなく、他の動物から類を見ないこの情熱によって際立っています。それは心の欲望であり、絶え間ない絶え間ない知識の生成における喜びの忍耐によって、肉欲的な快楽の短い激しさを超えます。 .


期待される出力:

TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4= 

( Base64 のウィキペディアのページから)


実際の出力:

YW7MaXPMZGnMdGnMZ3XMc2jMZCzMbm/MIG/MbHnMYnnMaGnMIHLMYXPMbizMYnXMIGLMIHTMaXPMc2nMZ3XMYXLMcGHMc2nMbiDMcm/MIG/MaGXMIGHMaW3MbHPMIHfMaWPMIGnMIGHMbHXMdCDMZiDMaGXMbWnMZCzMdGjMdCDMeSDMIHDMcnPMdmXMYW7MZSDMZiDMZWzMZ2jMIGnMIHTMZSDMb27MaW7MZWTMYW7MIGnMZGXMYXTMZ2HMbGXMZ2XMZXLMdGnMbiDMZiDMbm/MbGXMZ2XMIGXMY2XMZHPMdGjMIHPMb3LMIHbMaGXMZW7MZSDMZiDMbnnMY2HMbmHMIHDMZWHMdXLMLnLM

コード:

#include <iostream>
#include <fstream>

char Base64Table[64] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z', //0-25
                        'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', //26-51
                        '0','1','2','3','4','5','6','7','8','9',                                                                 //52-61
                        '+','/'};                                                                                                //62-63
char PADDING_CHAR = '=';

char GetFirstSymbol(char* buffer);
char GetSecondSymbol(char* buffer);
char GetThirdSymbol(char* buffer);
char GetFourthSymbol(char* buffer);

int main(int argc, char** argv) {

    if(argc != 2) {
        std::cout << "Incorrect number of arguments." << std::endl;
        std::cout << "Press Enter to quit.";
        while(!std::cin.get());
        return 0;
    }

    std::cout << "Converting " << argv[1] << std::endl;

    std::ifstream input;
    input.open(argv[1], std::ios_base::binary);

    std::ofstream output;
    output.open("data.base64", std::ios_base::binary);

    char count[1] = {'\0'};
    unsigned long file_size = 0;
    char buffer[3] = {'\0', '\0', '\0'};
    while(input.fail() == false) {
        input.read(reinterpret_cast<char*>(count), sizeof(count));
        ++file_size;
    }
    input.clear();
    input.seekg(0);

    while(input.fail() == false) {
        input.read(reinterpret_cast<char*>(buffer), sizeof(buffer));
        char firstsymbol = GetFirstSymbol(buffer);
        char secondsymbol = GetSecondSymbol(buffer);
        char thirdsymbol = GetThirdSymbol(buffer);
        char fourthsymbol = GetFourthSymbol(buffer);

        output.write(reinterpret_cast<char*>(&firstsymbol), sizeof(firstsymbol));
        output.write(reinterpret_cast<char*>(&secondsymbol), sizeof(secondsymbol));
        if(file_size % 3 == 2) {
            output.write(reinterpret_cast<char*>(&PADDING_CHAR), sizeof(PADDING_CHAR));
            continue;
        } else if(file_size % 3 == 1) {
            output.write(reinterpret_cast<char*>(&PADDING_CHAR), sizeof(PADDING_CHAR));
            output.write(reinterpret_cast<char*>(&PADDING_CHAR), sizeof(PADDING_CHAR));
            continue;
        }
        output.write(reinterpret_cast<char*>(&thirdsymbol), sizeof(thirdsymbol));
        output.write(reinterpret_cast<char*>(&fourthsymbol), sizeof(fourthsymbol));
    }
    input.clear();
    input.close();

    output.clear();
    output.close();

    return 0;
}

//Gets the 6 most significant digits of the first byte.
char GetFirstSymbol(char* buffer) {
    int index = (buffer[1] >> 2);
    return Base64Table[index];
}

//Gets the 2 least significant digits from previous (first) byte and 4 most significant from the second byte.
char GetSecondSymbol(char* buffer) {
    int index = (((buffer[1] & 0x03) << 4) | ((buffer[2] & 0xF0) >> 4));
    return Base64Table[index];
}

//Gets the 4 least significant digits from previous (second) byte and 2 least significant from the third byte.
char GetThirdSymbol(char* buffer) {
    int index = (((buffer[2] & 0x0F) << 2) | ((buffer[3] & 0xC0) >> 6));
    return Base64Table[index];
}

//Gets the 6 least significant digits from the third byte.
char GetFourthSymbol(char* buffer) {
    int index = (buffer[3] & 0x3F);
    return Base64Table[index];
}
4

1 に答える 1

2

C/C++ ポインターと配列は非常に強力な獣ですが、害を及ぼす可能性もあります。そのため、それらを扱うときは注意が必要です。として定義bufferchar[3]ますが、インデックス [1] からインデックス [3] にアクセスします。C/C++ 配列のインデックスは 0 ベースであるため、これはエラーです。これによれば、変更せずbuffer [0][1][2][memory of other variables]に残しbuffer[0]、代わりにメモリに書き込みます。これがランダムエラーと無効な値の原因です!!!

于 2012-09-16T21:38:10.027 に答える