[英]C++ How to convert a big integer in std::string form to byte/char-array/vector
我目前正在使用一个到目前为止看起来非常有用的BigInt 库。
但我想将计算结果存储到二进制文件中以备后用。
由于原因(二进制模式、文件大小等),仅存储字符串不是一种选择。
必须存储实际值以供以后读取。
我正在寻找的示例代码:
BigInt example = BigInt("4");
std::vector<uint8_t> bytes = to_bytes(example);
想要的结果示例:
"4" ---> [0000 0100] //BigInt("4");
"255" --> [1111 1111] //BigInt("256");
"542" --> [0000 0010] [0001 1110] //...
"123456" --> [0000 0001] [1110 0010] [0100 0000]
“高得离谱的数字” --> [?] [?] [?] [?]... [n-bytes]
当然反过来:
std::vector<uint8_t> bytes = readbytes(file, n-bytes);//already have this
BigInt result = from_bytes(bytes);
所以基本上,我需要to_bytes()
和from_bytes()
函数。
我正在使用 C++20。
价值观都是积极的,但两种解决方案都是受欢迎的。
最好找到一个内置此功能的大整数库。 这个库甚至没有 shift 运算符支持。 因此,您将不得不做一堆可能非常慢的事情(特别是考虑到该库对字符串进行大整数数学运算)并且比它给您一个体面的界面要慢得多。
要将这么大的 integer 转换为一系列字节,您必须单独重复提取每个字节的数据。 这里的“字节”是每 2 8个数字。 如果没有位移运算符,它将涉及很多除法和模运算。
std::uint8_t extract_one_byte(BigInt &extract)
{
auto intermediate = (extract % 256).to_int(); //Will always return a value on the range [0, 255]
std::uint8_t the_byte = static_cast<std::uint8_t>(intermediate);
extract /= 256;
return the_byte;
}
std::vector<std::uint8_t> to_bytes(const BigInt &source)
{
std::vector<std::uint8_t> ret;
//ret.reserve(#); //pick a decent amount to reserve.
BigInt curr = source;
do
{
ret.push_back(extract_byte(curr));
} while(curr != 0);
return ret;
}
请注意,这会以 little-endian 顺序提取字节(最低有效优先)。 如果你需要大端,那么你必须在构造后std::reverse
vector
。 向后构建向量涉及更多的数据复制。
回去基本上是做相反的事情(从小端):
BigInt from_bytes(const std::vector<std::uint8_t> &le_bytes)
{
BigInt ret = 0;
for(auto curr_byte : le_bytes)
{
ret *= 256;
ret += curr_byte;
}
return ret;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.