From ec0669845b9072ea6cdc0fefb66f1d07511386a4 Mon Sep 17 00:00:00 2001 From: Linus Jahn Date: Fri, 12 Aug 2022 18:00:10 +0200 Subject: Utils_p: Add functions to generate random QByteArray Co-authored-by: Melvin Keskin --- src/base/QXmppUtils.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ src/base/QXmppUtils_p.h | 22 ++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/base/QXmppUtils_p.h (limited to 'src/base') diff --git a/src/base/QXmppUtils.cpp b/src/base/QXmppUtils.cpp index 1d99a87f..462d19fb 100644 --- a/src/base/QXmppUtils.cpp +++ b/src/base/QXmppUtils.cpp @@ -6,6 +6,7 @@ #include "QXmppUtils.h" #include "QXmppLogger.h" +#include "QXmppUtils_p.h" #include #include @@ -322,3 +323,69 @@ void helperToXmlAddTextElement(QXmlStreamWriter *stream, const QString &name, else stream->writeEmptyElement(name); } + +/// \cond + +// +// Generates a random count of random bytes. +// +// \param minimumByteCount minimum count of bytes to generate +// \param maximumByteCount maximum count of bytes to generate +// +// \return the generated bytes +// +QByteArray QXmpp::Private::generateRandomBytes(uint32_t minimumByteCount, uint32_t maximumByteCount) +{ +#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) + const auto byteCount = QRandomGenerator::system()->bounded(minimumByteCount, maximumByteCount); +#else + const auto byteCount = (qrand() % (maximumByteCount - minimumByteCount)) + minimumByteCount; +#endif + QByteArray bytes; + bytes.resize(byteCount); + generateRandomBytes(reinterpret_cast(bytes.data()), byteCount); + + return bytes; +} + +// +// Generates random bytes. +// +// \param bytes generated bytes +// \param byteCount count of bytes to generate +// +void QXmpp::Private::generateRandomBytes(uint8_t *bytes, uint32_t byteCount) +{ + // QRandomGenerator does not provide a random generation of single bytes. Thus, this approach + // fills an array with unsigned integers until no additional integer fits into the array. If + // byteCount is no multiple of intSize, the remaining bytes need to be filled separately. + constexpr uint32_t intSize = sizeof(uint32_t); + auto intCount = byteCount / intSize; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) + auto *randomGenerator = QRandomGenerator::system(); + + // Fill the space with intCount unsigned integers. + if (intCount) { + randomGenerator->fillRange(reinterpret_cast(bytes), intCount); + } + + // Fill the remaining space with single bytes. + for (size_t i = byteCount - byteCount % intSize; i < byteCount; i++) { + bytes[i] = randomGenerator->bounded(std::numeric_limits::max() + 1); + } +#else + // Fill the range with intCount unsigned integers. + for (size_t i = 0; i < intCount; i++) { + reinterpret_cast(bytes)[i] = qrand(); + } + + // Fill the remaining space with single bytes. + for (size_t i = byteCount - byteCount % intSize; i < byteCount; i++) { + auto rand = qrand(); + bytes[i] = *reinterpret_cast(&rand) % (std::numeric_limits::max() + 1); + } +#endif +} + +/// \endcond diff --git a/src/base/QXmppUtils_p.h b/src/base/QXmppUtils_p.h new file mode 100644 index 00000000..9a7b6103 --- /dev/null +++ b/src/base/QXmppUtils_p.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: 2022 Linus Jahn +// SPDX-FileCopyrightText: 2022 Melvin Keskin +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#ifndef QXMPPUTILS_P_H +#define QXMPPUTILS_P_H + +#include "QXmppGlobal.h" + +#include + +#include + +namespace QXmpp::Private { + +QXMPP_EXPORT QByteArray generateRandomBytes(uint32_t minimumByteCount, uint32_t maximumByteCount); +QXMPP_EXPORT void generateRandomBytes(uint8_t *bytes, uint32_t byteCount); + +} // namespace QXmpp::Private + +#endif // QXMPPUTILS_P_H -- cgit v1.2.3