Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to convert a boost::multiprecision::cpp_int to QByteArray



  • How can I convert a cpp_int to a binary QByteArray? I already convert a quint32 to a QByteArray with the following function:

    QByteArray MySmallNumber::intToByteArray(QDataStream::ByteOrder byteOrder)
    {
        // Convert the int to QByteArray
        QByteArray intByteArray;
        QDataStream intDataStream(&intByteArray, QIODevice::WriteOnly);
    
        // The default setting is big endian.
        // We recommend leaving this setting unless you have special requirements.
        //intDataStream.setByteOrder(m_byteOrder);
        intDataStream.setByteOrder(byteOrder);
        intDataStream << m_intNumber;
    
        return intByteArray;
    }
    


  • @Infinity

    Since cpp_int is apparently supporting output operator<< according to this here, you could go through std::ostringstream.

    Possibly there is a more elegant possibility.


  • Lifetime Qt Champion

    You already had a conversion in your previous post some days ago - did it not work?
    https://forum.qt.io/topic/111466/convert-64-byte-qbytearray-to-two-32-byte-int/8



  • @Christian-Ehrlicher The code in my previous post worked, but I this time I wanted to have it in binary format. It sometimes helps me to ask questions to find the right solution :-)

    Now I came up with the following solution:

    QByteArray MyBigNumber::byteArrayHex()
    {
        // See https://www.systutorials.com/131/convert-string-to-int-and-reverse/
    
        // Convert the cpp_int to a hex std::string
        std::string str;
        std::stringstream stream;
        stream << std::hex << m_cppInt;
        str = stream.str();
    
        // Convert the hex std::string to a binary QByteArray
        return QByteArray::fromHex(QByteArray::fromStdString(str));
    }
    

    How does that look like?


  • Moderators

    boost's multiprecision keeps the data in tuples of binary, but you can use bitshifts to just extract it byte by byte (as with any other number). Something along these lines:

    typedef decltype(m_cppInt) BigInt;
    constexpr int bytes = std::numeric_limits<BigInt>::digits / 8;
    constexpr quint8 mask = quint8(-1);
    constexpr quint8 shift = sizeof(quint8) * 8;
    
    QByteArray data(bytes, 0);
    for (int i = 0; i < bytes; i++)  {
        data[bytes - i - 1] = quint8(m_cppInt & mask);
        m_cppInt >>= shift;
    }
    


  • boost multiprecision can serialise/deserialise itself.

    std::vector<char> chars;
    boost::iostreams::stream_buffer<boost::iostreams::back_insert_device<std::vector<char> > > bb(chars);
    boost::archive::binary_oarchive oa(bb, boost::archive::no_header | boost::archive::no_tracking | boost::archive::no_codecvt);
    oa << m_cppInt;
    QByteArray serialised(chars.data(),chars.size());
    

    See https://stackoverflow.com/questions/50465041/how-to-convert-boostmultiprecisioncpp-int-tofrom-an-array-of-byte

    P.S.
    boost::iostreams::back_insert_device might work directly with QByteArray as well without the need to use the std::vector<char> indirection but I have no way of testing it atm, feel free to explore that option


Log in to reply