如何将字节数组转换为 boost::multiprecision::uint128_t?

Posted

技术标签:

【中文标题】如何将字节数组转换为 boost::multiprecision::uint128_t?【英文标题】:How do I convert an array of bytes to a boost::multiprecision::uint128_t? 【发布时间】:2018-10-23 21:42:52 【问题描述】:

如果我有:

char buffer[16];

如何将其原始字节转换为:

boost::multiprecision::uint128_t?

我尝试做一个标准的 C 风格转换:

uint128_t myInt = *(uint128_t*)buffer;

虽然它似乎不能正常工作。还尝试使用 dynamic_cast

我找到了这个页面:https://www.boost.org/doc/libs/1_56_0/libs/multiprecision/doc/html/boost_multiprecision/tut/conversions.html

关于如何进行对话,但似乎没有涵盖这类事情。有什么想法吗?

编辑: 其中一个 cmets 建议使用 memcpy(如果它类似于 GCC 的 128 位 uint)将字节复制到 uint128_t 中。如果按照我期望的方式完成,这似乎无法正常工作: 我错过了什么吗?

【问题讨论】:

This 可能会有所帮助 缓冲区的格式是什么? 这个想法只是字节缓冲区。所以也许 0xAA 0xBB 0xCC.. 如果它的行为类似于 GCC 的uint128_t,那么你可以将memcpybuffer 转换成变量。 【参考方案1】:

我找到了一种基于 uint128_t 类型的动态特性的方法。似乎并非始终将所有 16 个字节用于数值。它仅在认为需要它们时才使用它们(这就是原始 memcpy() 不起作用的原因)。

所以诀窍是强制它认为需要所有 16 个字节,然后 memcpy() 将数据输入。我们可以通过设置初始值 -1(或所有 Fs)来做到这一点:

boost::multiprecision::uint128_t getUintFromBuffer(const std::vector<unsigned char> &buf)

    boost::multiprecision::uint128_t retU = -1;
    memset(&retU, 0, 16);
    memcpy(&retU, buf.data(), std::min(buf.size(), (size_t)16));
    return retU;


int main()

    std::vector<unsigned char> buf;
    buf.resize(16);
    buf[0] = 0xaa;
    buf[15] = 0xff;

    std::cout << std::hex << getUintFromBuffer(buf) << std::endl;

    return EXIT_SUCCESS;

运行此示例会打印: FF0000000000000000000000000000AA

这就是我一直在寻找的 :)

【讨论】:

【参考方案2】:

我建议您可能正在寻找 this:

#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
#include <iomanip>
#include <vector>
#include <iterator>

int main()

   using boost::multiprecision::cpp_int;
   // Create a cpp_int with just a couple of bits set:
   cpp_int i;
   bit_set(i, 5000); // set the 5000'th bit
   bit_set(i, 200);
   bit_set(i, 50);
   // export into 8-bit unsigned values, most significant bit first:
   std::vector<unsigned char> v;
   export_bits(i, std::back_inserter(v), 8);
   // import back again, and check for equality:
   cpp_int j;
   import_bits(j, v.begin(), v.end());
   assert(i == j);

【讨论】:

【参考方案3】:

我发现只使用boost::multiprecision::import_bits 就可以了。

template <unsigned Bits, boost::multiprecision::cpp_integer_type SignType,
          boost::multiprecision::cpp_int_check_type Checked>
boost::multiprecision::number<
    boost::multiprecision::cpp_int_backend<Bits, Bits, SignType, Checked, void>>
rawToBoost(const void *V) 
  using namespace boost::multiprecision;

#if BOOST_ENDIAN_BIG_BYTE
  static const auto msv_first = true;
#else
  static const auto msv_first = false;
#endif

  number<cpp_int_backend<Bits, Bits, SignType, Checked, void>> ret;
  auto VPtr = reinterpret_cast<const unsigned char *>(V);
  import_bits(ret, VPtr, VPtr + (Bits / 8), 0, msv_first);
  return ret;


boost::multiprecision::int128_t rawToBoost_int128(const void *V) 
  using namespace boost::multiprecision;
  return rawToBoost<128, signed_magnitude, unchecked>(V);


boost::multiprecision::int128_t rawToBoost_int128_safe(const void *V) 
  using namespace boost::multiprecision;
  return rawToBoost<128, signed_magnitude, checked>(V);


boost::multiprecision::uint128_t rawToBoost_uint128(const void *V) 
  using namespace boost::multiprecision;
  return rawToBoost<128, unsigned_magnitude, unchecked>(V);


boost::multiprecision::uint128_t rawToBoost_uint128_safe(const void *V) 
  using namespace boost::multiprecision;
  return rawToBoost<128, unsigned_magnitude, checked>(V);


这是 OP 提到的相同链接(但不同的增强版本)。 https://www.boost.org/doc/libs/1_62_0/libs/multiprecision/doc/html/boost_multiprecision/tut/ints/cpp_int.html

【讨论】:

以上是关于如何将字节数组转换为 boost::multiprecision::uint128_t?的主要内容,如果未能解决你的问题,请参考以下文章

如何将字节数组转换为字符串[重复]

如何将字节数组转换为流 [重复]

如何将字节数组转换为图片[关闭]

如何将字节数组的字符串转换为字节数组

如何将字节数组转换为整数数组

如何将字符串转换为字节数组? [关闭]