Я пытаюсь преобразовать Integer в строку со следующим кодом:
CryptoPP::Integer i("12345678900987654321");
std::ostrstream oss;
oss << i;
std::string s(oss.str());
LOGDEBUG(oss.str()); // Pumps log to console and log file
появляется выход, чтобы иметь дополнительные данные для мусора:
12345678900987654321.ÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««îþîþ
Я не могу воспроизвести это с Crypto ++ 5.6.2 в Visual Studio 2010. Поврежденный вывод, скорее всего, является результатом какой-то другой проблемы, а не ошибки в Crypto ++. Если вы еще этого не сделали, я предлагаю попытаться воспроизвести это в минимальной программе, используя CryptoPP::Integer
и std::cout
, и ни один из ваших других кодов приложений, чтобы устранить все другие возможные проблемы. Если он не работает в тривиальном автономном тесте (что было бы удивительно), могут возникнуть проблемы с тем, как была построена библиотека (например, возможно, она была построена с использованием другой версии C++ или версии компилятора из того, что использует ваше приложение) , Если ваш автономный тест проходит, вы можете добавить другие строковые операции, код регистрации и т. Д., Пока не найдете виновника.
Я замечаю, что вы используете std::ostrstream
, который устарел. Вы можете использовать std::ostringstream
instead. This Stack Overflow answer to the question "Why was std::strstream deprecated?" может представлять интерес, и даже в случае, если проблемы, упомянутые в этом ответе, вызывают проблемы.
Кроме того, я не могу получить точность или научную нотацию. следующий вывод будет тот же результат:
std::cout.precision(5); // Does nothing with CryptoPP::Integer
std::cout << "Dec: " << std::setprecision(1) << std::dec << i << std::endl;
std::cout << "Sci: " << std::setprecision(5) << std::scientific << i << std::endl;
std::setprecision
и std::scientific
modify floating-point input/output.Таким образом, с обычными целыми типами в C++, например int
или long long
, это тоже не сработает (но я вижу, что особенно с целыми числами произвольной длины, такими как CryptoPP:Integer
, возможность вывода в научной нотации с определенной точностью имела бы смысл).
Даже если C++ не определял его так, реализация Crypto ++ все равно должна была учитывать эти флаги. От взгляда на реализацию Crypto ++ std::ostream& operator<<(std::ostream& out, const Integer &a)
я вижу, что единственными признаками iostream, которые он распознает, являются std::ios::oct
и std::ios::hex
(для восьмеричных и шестнадцатеричных чисел соответственно).
Если вам нужна научная нотация, вам придется самостоятельно форматировать выход (или использовать другую библиотеку).
Вдобавок ко всему, достаточно большие количества ломают всю вещь .
CryptoPP::Integer i("12345");
// Calculate i^16
for (int x = 0; x < 16; x++)
{
i *= i;
}
std::cout << i << std::endl; // Will never finish
Это будет на самом деле вычислить i^(2^16) = i^65536
, не i^16
, потому что на каждом цикле вы умножая i
с новым промежуточным значением, а не с его первоначальным значением. Фактический результат с этим кодом должен составлять 268,140 цифр, поэтому я ожидаю, что он просто запустит Crypto ++ для получения этого вывода.
Вот код корректируется, чтобы получить правильный результат:
CryptoPP::Integer i("12345");
CryptoPP::Integer i_to_16(1);
// Calculate i^16
for (int x = 0; x < 16; x++)
{
i_to_16 *= i;
}
std::cout << i_to_16 << std::endl;
Показать определение 'LOGDEBUG'. Похоже, вы вызываете 'printf' и передаете строковый объект, возвращаемый из' ostrstream', вместо указателя на текстовый буфер. Поскольку не было сделано никакого вызова, чтобы заставить буфер быть завершенным нулем, возможно, вы увидите, что после текста появится мусор. Попробуйте 'LOGDEBUG (oss.str(). C_str())' –
Совершенно откровенно, LOGDEBUG здесь не проблема. Как указано в моем сообщении, std :: cout производит тот же вывод. Я мог бы полностью удалить свой материал Urho3D (включая LOGDEBUG), и std :: cout все равно будет работать с той же проблемой. – Thebluefish
* «Вдобавок ко всему, достаточно большие числа ломают всю вещь» * - да, это документированное поведение. Точный размер * абсолютное значение меньше, чем '(256 ** sizeof (word)) ** (256 ** sizeof (int))' *. См. Комментарии в [Целочисленный заголовочный файл] (http://www.cryptopp.com/docs/ref/integer_8h_source.html). Это ужасно большое число, даже для криптографии. Возможно, вам следует перейти в библиотеку, которая обеспечивает целочисленное целое, например [GNU's Multiprecision Integer] (https://gmplib.org/) (gmp). – jww