我有一个std::string
,其中有一个用Base16编码的大整数:
bbb91c1c95b656f386b19ab284b9c0f66598e7761cd71569734bb72b6a7153b77613a6cef8e63
e9bd9bb1e0e53a0fd8fa2162b160fcb7b461689afddf098bfc32300cf6808960127f1d9f0e287
f948257f7e0574b56585dd1efe1192d784b9c93f9c2215bd4867062ea30f034265374fa013ab4
5af06cd8554fd55f1c442c2ed
我想要一个在Base10中编码大整数的std::string
:
13182363340585954094154991955162141609757130565683854218475776626603716062690
50741824486137510938646762753180989129520441058729412931959771922633699694948
46611764803267065720664398942078304585998290003537553345030144535441671492050
01138054588415687622649540474976282005406232907125282540703919964112809484362
9
如何将字符串从Base16转换为Base10?
答案 0 :(得分:1)
由于您不想要图书馆,因此您需要一些代码。这不是一个微不足道的问题,但也不是太复杂。让我们从my Bignum
class from another answer开始,并为其添加几个函数。
class Bignum
{
//...
Bignum& operator+=(int rhs)
{
assert(rhs >= 0 && rhs <= 999999999);
uint32_t carry = rhs;
for (size_t i = 0; i < parts.size(); i++)
{
uint32_t sum = parts[i] + carry;
parts[i] = (uint32_t)(sum % 1000000000UL);
carry = (uint32_t)(sum / 1000000000UL);
}
if (carry != 0)
parts.push_back(carry);
return *this;
}
void FromHex(const char * pString)
{
while (*pString != 0)
{
char ch = toupper(*pString++);
assert((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F'));
int digit = (ch <= '9') ? (ch - '0') : (ch - 'A' + 10);
*this *= 16;
*this += digit;
}
}
答案 1 :(得分:1)
将编码的std :: string从Base16转换为Base10?
以下内容适合您。下面的代码向您展示了如何使用C风格的字符串,这很容易概念化。您在Convert CryptoPP::Integer to LPCTSTR上的上一个问题有参考资料。
#include <iostream>
#include <string>
using namespace std;
#include "cryptlib.h"
#include "integer.h"
using namespace CryptoPP;
int main(int argc, char* argv[])
{
string s2, s1 =
"bbb91c1c95b656f386b19ab284b9c0f66598e7761cd71569734bb72b6a7153b77613a6cef8e63"
"e9bd9bb1e0e53a0fd8fa2162b160fcb7b461689afddf098bfc32300cf6808960127f1d9f0e287"
"f948257f7e0574b56585dd1efe1192d784b9c93f9c2215bd4867062ea30f034265374fa013ab4"
"5af06cd8554fd55f1c442c2ed";
// Append 'h' to indicate Base16
// Integer n((s1 + "h").c_str());
// Prepend '0x' to indicate Base16
Integer n(("0x" + s1).c_str());
// Convert to Base10
s2 = IntToString<Integer>(n, 10);
cout << s2 << endl;
return 0;
}
上面的代码向您展示了如何使用C风格的字符串进行操作,这很容易概念化。另一种方法是使用Crypto ++ Pipeline
将ASCII字符串转换为big-endian字节数组。
#include <iostream>
#include <string>
using namespace std;
#include "cryptlib.h"
#include "integer.h"
#include "filters.h"
#include "hex.h"
using namespace CryptoPP;
int main(int argc, char* argv[])
{
string s3, s2, s1 =
"bbb91c1c95b656f386b19ab284b9c0f66598e7761cd71569734bb72b6a7153b77613a6cef8e63"
"e9bd9bb1e0e53a0fd8fa2162b160fcb7b461689afddf098bfc32300cf6808960127f1d9f0e287"
"f948257f7e0574b56585dd1efe1192d784b9c93f9c2215bd4867062ea30f034265374fa013ab4"
"5af06cd8554fd55f1c442c2ed";
// Use a HexDecoder to convert to big-endian array
StringSource ss(s1, true, new HexDecoder(new StringSink(s2)));
// Use big-endian array to construct n
Integer n((const byte*)s2.data(), s2.size());
// Convert to Base10
s3 = IntToString<Integer>(n, 10);
cout << s3 << endl;
return 0;
}
这是使用Crypto ++ Pipeline
执行转换的另一种方法。
#include <iostream>
#include <string>
using namespace std;
#include "cryptlib.h"
#include "integer.h"
#include "filters.h"
#include "hex.h"
using namespace CryptoPP;
int main(int argc, char* argv[])
{
string s2, s1 =
"bbb91c1c95b656f386b19ab284b9c0f66598e7761cd71569734bb72b6a7153b77613a6cef8e63"
"e9bd9bb1e0e53a0fd8fa2162b160fcb7b461689afddf098bfc32300cf6808960127f1d9f0e287"
"f948257f7e0574b56585dd1efe1192d784b9c93f9c2215bd4867062ea30f034265374fa013ab4"
"5af06cd8554fd55f1c442c2ed";
// Use a source to convert to big-endian array
StringSource ss(s1, true, new HexDecoder);
// Use big-endian array to construct n
Integer n;
n.Decode(ss, ss.MaxRetrievable());
// Convert to Base10
s2 = IntToString<Integer>(n, 10);
cout << s2 << endl;
return 0;
}
如果您对将ASCII字符串转换为字节数组以进行内部表示的算法感兴趣,请参阅StringToInteger
in integer.cpp
。它反复划分为基数(2,8,10,16等)。