Декодировать огромное количество данных, закодированных в base64 в c ++ - PullRequest
0 голосов
/ 08 мая 2018

У меня есть строковая переменная типа 1 801 048 символов, закодированная в base64, и я хочу их декодировать. У меня есть этот фрагмент, который хорошо работает с более короткими строками, однако, когда я помещаю 1 801 048 данных, это вызывает ошибки.

Это фрагмент:

static inline bool is_base64(unsigned char c) 
{
    return (isalnum(c) || (c == '+') || (c == '/'));
}

string base64_decode(string const& encoded_string) 
{
    int in_len = encoded_string.size();
    int i = 0;
    int j = 0;
    int in_ = 0;
    unsigned char char_array_4[4], char_array_3[3];
    string ret;

    while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) 
    {
        char_array_4[i++] = encoded_string[in_]; in_++;

        if (i ==4) 
        {
            for (i = 0; i < 4; i++)
            {
                char_array_4[i] = base64_chars.find(char_array_4[i]);
            }

            char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
            char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
            char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

            for (i = 0; (i < 3); i++)
            {
                ret += char_array_3[i];
            }

            i = 0;
        }
    }

    if (i) 
    {
        for (j = i; j < 4; j++)
        {
            char_array_4[j] = 0;
        }

        for (j = 0; j < 4; j++)
        {
            char_array_4[j] = base64_chars.find(char_array_4[j]);
        }

        char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
        char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
        char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

        for (j = 0; (j < i - 1); j++)
        {
            ret += char_array_3[j];
        }   
    }

    return ret;
}

Вот как я его использую, но это вызывает закрытие программы или переполнение памяти (думаю, я не уверен):

string base64_encoded_data = "UEsDBBQAAAAIAI1Wp0xrN4dXHwIAA...." //Size = 1,801,048
string base64_decoded_data = base64_decode(base64_encoded_data);

Где ошибка или как я могу улучшить программу, чтобы обесцвечивание происходило правильно? Ввод и вывод данных должны быть строкового типа.

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

Вероятно, проблема в том, как вы строите возвращаемую строку ret.Вы добавляете по одному символу за раз, поэтому строка будет периодически наращивать емкость.Из-за размера выделенных блоков и работы кучи это оставит много нераспределенного, но все еще используемого пространства кучи.

Поскольку вы можете вычислить размер, необходимый для возвращаемой строки, вы можете использовать

ret.reserve((in_len * 3 + 3) / 4);

перед циклом while, чтобы выделить один буфер, достаточно большой для всей строки.Это позволит избежать всех дополнительных выделений памяти и позволит вам декодировать ваши большие строки.

0 голосов
/ 08 мая 2018

Поскольку вы используете пользовательское устройство, возможно, вы пытаетесь сохранить больше, чем может хранить обычная строка. Строки имеют максимальный размер (, здесь вы можете посмотреть, как проверить ). Вы должны проверить, соответствует ли это вашему варианту использования, если нет, возможно, использовать буфер. Если размер в порядке, требуется больше информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...