如何将 boost::asio::ip::address_v6 IP 转换为 2 uint64_t 数字并从 2 uint64_t 转换回 v6 地址?
How to convert boost::asio::ip::address_v6 IP into 2 uint64_t numbers and back from 2 uint64_t to v6 address?
我通过执行以下操作首先将 boost::asio::ip::address_v6
IP(例如 1456:94ce:2567:a4ef:1356:94de:2967:a4e8
)转换为 16 字节 unsigned char
数组:
auto ip = boost::asio::ip::address_v6::from_string("1456:94ce:2567:a4ef:1356:94de:2967:a4e8");
auto v6Bytes = ip.boost::asio::ip::address_v6::to_bytes();
现在我的下一个 objective 是使用字节数组中的 8 个字节并将它们转换为 uint64_t
(假设我得到 num1
)。同样,使用数组中接下来的 8 个字节,我想生成另一个 uint64_t
(比如 num2
)。这里可以用什么逻辑来转换?
此外,一旦我得到 num1
和 num2
,我想使用它们并转换回
std::array<unsigned char, 16>
我可以在这里使用什么逻辑?
唯一受支持的方法是使用 std::memcpy
。将前八个字节复制到一个变量中,然后将其他八个字节复制到第二个变量中。
这可以很容易地用 &
的地址运算符和指针算法来完成:
std::uint64_t part1, part2;
std::memcpy(&part1, v6Bytes.data(), 8);
std::memcpy(&part2, v6Bytes.data() + 8, 8);
以相反的方式将数据复制回数组。
我会假设原始数组是网络字节顺序(bigendian)并做这样的事情:
auto ip = boost::asio::ip::address_v6::from_string("1456:94ce:2567:a4ef:1356:94de:2967:a4e8");
auto v6Bytes = ip.boost::asio::ip::address_v6::to_bytes();
std::uint64_t num1;
std::uint64_t num2;
std::copy(std::begin(v6Bytes), std::begin(v6Bytes) + std::size(v6Bytes) / 2, (unsigned char*)&num1);
std::copy(std::begin(v6Bytes) + std::size(v6Bytes) / 2, std::end(v6Bytes), (unsigned char*)&num2);
// assume network byte order
boost::endian::big_to_native(num1);
boost::endian::big_to_native(num2);
// and back again
std::array<unsigned char, 16> bytes;
boost::endian::native_to_big(num1);
boost::endian::native_to_big(num2);
std::copy((unsigned char*)&num1, ((unsigned char*)&num1) + 8, bytes.data());
std::copy((unsigned char*)&num2, ((unsigned char*)&num2) + 8, bytes.data() + 8);
assert(bytes == v6Bytes);
我通过执行以下操作首先将 boost::asio::ip::address_v6
IP(例如 1456:94ce:2567:a4ef:1356:94de:2967:a4e8
)转换为 16 字节 unsigned char
数组:
auto ip = boost::asio::ip::address_v6::from_string("1456:94ce:2567:a4ef:1356:94de:2967:a4e8");
auto v6Bytes = ip.boost::asio::ip::address_v6::to_bytes();
现在我的下一个 objective 是使用字节数组中的 8 个字节并将它们转换为 uint64_t
(假设我得到 num1
)。同样,使用数组中接下来的 8 个字节,我想生成另一个 uint64_t
(比如 num2
)。这里可以用什么逻辑来转换?
此外,一旦我得到 num1
和 num2
,我想使用它们并转换回
std::array<unsigned char, 16>
我可以在这里使用什么逻辑?
唯一受支持的方法是使用 std::memcpy
。将前八个字节复制到一个变量中,然后将其他八个字节复制到第二个变量中。
这可以很容易地用 &
的地址运算符和指针算法来完成:
std::uint64_t part1, part2;
std::memcpy(&part1, v6Bytes.data(), 8);
std::memcpy(&part2, v6Bytes.data() + 8, 8);
以相反的方式将数据复制回数组。
我会假设原始数组是网络字节顺序(bigendian)并做这样的事情:
auto ip = boost::asio::ip::address_v6::from_string("1456:94ce:2567:a4ef:1356:94de:2967:a4e8");
auto v6Bytes = ip.boost::asio::ip::address_v6::to_bytes();
std::uint64_t num1;
std::uint64_t num2;
std::copy(std::begin(v6Bytes), std::begin(v6Bytes) + std::size(v6Bytes) / 2, (unsigned char*)&num1);
std::copy(std::begin(v6Bytes) + std::size(v6Bytes) / 2, std::end(v6Bytes), (unsigned char*)&num2);
// assume network byte order
boost::endian::big_to_native(num1);
boost::endian::big_to_native(num2);
// and back again
std::array<unsigned char, 16> bytes;
boost::endian::native_to_big(num1);
boost::endian::native_to_big(num2);
std::copy((unsigned char*)&num1, ((unsigned char*)&num1) + 8, bytes.data());
std::copy((unsigned char*)&num2, ((unsigned char*)&num2) + 8, bytes.data() + 8);
assert(bytes == v6Bytes);