2016-08-26 4 views
1

Я использую Crypto ++ 5.6.3 и мне нужна функция FileSource Skip(...). К сожалению, эта функция ничего не делает!Пропуск по источнику не работает должным образом

Вот пример этого function.

string filename = ...; 
string str; 

FileSource file(filename, false, new HexEncoder(new StringSink(str))); 
file.Skip(24); 
file.PumpAll(); 

Может кто-нибудь мне помочь?

+1

Добро пожаловать в переполнение стека! Похоже, вам, возможно, потребуется научиться использовать отладчик для выполнения вашего кода. С хорошим отладчиком вы можете выполнить свою программу по очереди и посмотреть, где она отклоняется от ожидаемого. Это важный инструмент, если вы собираетесь заниматься программированием. Дальнейшее чтение: ** [Как отлаживать небольшие программы] (http://ericlippert.com/2014/03/05/how-to-debug-small-programs/) ** –

+1

Странно, это буквально один из примеров обыкновения. Возможно, вы можете предоставить [Минимальный, полный и проверенный пример] (https://stackoverflow.com/help/mcve)? – Elijan9

ответ

1

Я использую Crypto ++ 5.6.3 и Ii нужен FileSource «пропустить (...) функция. К сожалению, эта функция ничего не делает!

Я был в состоянии дублировать это с помощью строки под Master, 5,6 . 0,3 и 5.6.2 на OS X 10.8.5 и Ubuntu 14.04

$ cat test.cxx 
#include <string> 
#include <iostream> 
using namespace std; 

#include <filters.h> 
#include <hex.h> 
using namespace CryptoPP; 

int main(int argc, char* argv[]) 
{ 
    string str1, str2; 
    HexEncoder enc(new StringSink(str1)); 
    for(unsigned int i=0; i < 32; i++) 
    enc.Put((byte)i); 
    enc.MessageEnd(); 

    cout << "str1: " << str1 <<endl; 

    StringSource ss(str1, false, new StringSink(str2)); 
    ss.Skip(10); 
    ss.PumpAll(); 

    cout << "str2: " << str2 << endl; 

    return 0; 
} 

и:

$ ./test.exe 
str1: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F 
str2: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F 

Crypto ++ 5.6.2 является значительным, потому что это была последняя версия, с которой Вэй работал, прежде чем превратить библиотеку в сообщество. Проблема в 5.6.2 является лишь скрытой ошибкой, и мы встречаемся с ними иногда, как и любой другой проект. (Ошибки «Вэй» на самом деле видны редко, и они ближе к ошибкам «Кнута» в его Art of Computer Programming).

Если это проблема 5.6.3 и выше, значит, сообщество сломало ее. Если сообщество сломало его, нам нужно выполнить посмертное исследование и проанализировать, как/почему нам удалось сломать то, что раньше работало.

Вот отчет об ошибке для библиотеки: Issue 248: Skip'ing on a Source does not work. Мы пытаемся определить, есть ли его ошибка; и если да, то как действовать.


EDIT 1: Я имел возможность исследовать этот вопрос немного больше. Вы можете прочитать анализ по адресу Comment 242890863. Короче говоря, Skip используется для отбрасывания байтов на выходном буфере (AttachedTransformation()), поэтому вещи несколько работает как ожидалось. Тем не менее, нет ничего интуитивного в отношении Skipне, работающий на Source, и только работающий на прилагаемом Filter (q.v., мы здесь).

Я также попросил некоторую обратную связь по списку рассылки по телефону Issue 248: Skip'ing on a Source does not work. DB и WD сразу заметили это - проблема дизайна в библиотеке.

Вот обходной путь, который вы можете использовать на данный момент. Эффективно, вы Pump() в nullFilter, который отбрасывает ввод, как ожидается. Затем вы присоединяете настоящую цепочку фильтров для обработки реальной обработки.

#include <string> 
#include <iostream> 
using namespace std; 

#include <filters.h> 
#include <hex.h> 
using namespace CryptoPP; 

int main(int argc, char* argv[]) 
{ 
    string str1, str2; 
    HexEncoder enc(new StringSink(str1)); 
    for(unsigned int i=0; i < 32; i++) 
    enc.Put((byte)i); 
    enc.MessageEnd(); 

    cout << "str1: " << str1 <<endl; 

    // 'ss' has a NULL AttachedTransformation() 
    StringSource ss(str1, false); 
    ss.Pump(10); 

    // Attach the real filter chain to 'ss' 
    ss.Attach(new StringSink(str2)); 
    ss.PumpAll(); 

    cout << "str2: " << str2 << endl; 

    return 0; 
} 

Он производит ожидаемый результат:

$ ./test.exe 
str1: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F 
str2: 05060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F 

В программе образца, я считаю, что обходной путь будет:

FileSource file(filename, false); 
file.Pump(24); 

file.Attach(new HexEncoder(new StringSink(str))); 
file.PumpAll(); 

EDIT 2: Вот немного более подробный способ достижения e работа вокруг (спасибо DB). Он подчеркивает, что байты отбрасываются. TheBitBucket() - это просто фильтр сброса, и он выполняет ту же функцию, что и nullAttachedTransformation().

int main(int argc, char* argv[]) 
{ 
    string str1, str2; 
    HexEncoder enc(new StringSink(str1)); 
    for(unsigned int i=0; i < 32; i++) 
    enc.Put((byte)i); 
    enc.MessageEnd(); 

    cout << "str1: " << str1 <<endl; 

    StringSource ss(str1, false, new Redirector(TheBitBucket())); 
    ss.Pump(10); 

    ss.Detach(new StringSink(str2)); 
    ss.PumpAll(); 

    cout << "str2: " << str2 << endl; 

    return 0; 
} 

Там другая тонкая разница в вышеуказанной программе: Он называет Detach, которая бесплатно это бывший цепной фильтр. Если вы вызвали Attach, тогда бывшая цепь была бы отсоединена, возвращена вызывающему, но не свободна.

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