如何将boost :: multiprecision :: cpp_int转换为字节数组中的& [英] how to convert boost::multiprecision::cpp_int to&from an array of byte

查看:88
本文介绍了如何将boost :: multiprecision :: cpp_int转换为字节数组中的&的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要两个功能:

std::vector<uint8_t> bigint_to_bytes(cpp_int a); 

cpp_int bytes_to_bigint(std::vector<uint8_t> const& a);

我用Google搜索,发现bigint_to_bytes可以通过 backend().limbs()来实现,并且不知道如何实现 bytes_to_bigint .

I googled and found the bigint_to_bytes can implement by backend().limbs(), and do not know how to implement the bytes_to_bigint.

如何通过字节数组构造 cpp_int ?

How can I construct a cpp_int by an array of byte?

推荐答案

boost中的序列化代码如下:

The serialize code in boost is as following:

template <class Archive, class Int>
void do_serialize(Archive& ar, Int& val, mpl::false_ const&, mpl::false_ const&, mpl::true_ const&)
{
   // Load.
   // Non-trivial.
   // Binary.
   bool s;
   std::size_t c;
   ar & s;
   ar & c;
   val.resize(c, c);
   ar.load_binary(val.limbs(), c * sizeof(limb_type));
   if(s != val.sign())
      val.negate();
   val.normalize();
}

template <class Archive, class Int>
void do_serialize(Archive& ar, Int& val, mpl::true_ const&, mpl::false_ const&, mpl::true_ const&)
{
   // Store.
   // Non-trivial.
   // Binary.
   bool s = val.sign();
   std::size_t c = val.size();
   ar & s;
   ar & c;
   ar.save_binary(val.limbs(), c * sizeof(limb_type));
}

cpp_int_detail::do_serialize(ar, val, save_tag(), trivial_tag(), binary_tag());

这里有关于数字符号的详细信息.

Here has a detail about number sign.

我做了一些测试,发现cpp_int始终使用big endian,因此即使在某些平台上,例如sizeof(limb_type)== 64或== 32,我也可以直接使用memcpy,如下所示:

I did some tests and found the cpp_int always use big endian, so even if on some platform, for example the sizeof(limb_type)==64 or ==32, I can use memcpy directly as following:

namespace {
using BigInt = mp::uint256_t;// boost::multiprecision::cpp_int;

// ignore sign, only support unsigned big integer
// it seems that cpp_int always use big endian
void BigIntToBytes(BigInt const& i, uint8_t* output, size_t len) {

    auto count = i.backend().size();
    auto tsize = sizeof(mp::limb_type);
    auto copy_count = count * tsize;
    if (len < count * tsize)
        throw std::runtime_error("len < count * tsize");
    memcpy(output, i.backend().limbs(), copy_count);
    if (len > copy_count) {
        memset(output + copy_count, 0, len - copy_count);
    }
}

BigInt BytesToBigInt(uint8_t const* output, size_t len) {
    if (len % sizeof(mp::limb_type))
        throw std::runtime_error("len % sizeof(mp::limb_type)");
    BigInt i;
    uint32_t size = (uint32_t)len / sizeof(mp::limb_type);
    i.backend().resize(size, size);
    memcpy(i.backend().limbs(), output, len);
    i.backend().normalize();
    return i;
}
}

这篇关于如何将boost :: multiprecision :: cpp_int转换为字节数组中的&amp;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆