问题描述
我需要将一个大(对于内置数据类型来说太大)的十六进制字符串转换为带有十进制表示形式的字符串。例如:
I need to convert a large (too large for the built-in data types) hex string to a string with it's decimal representation. For example:
std::string sHex = "07AA17C660F3DD1D2A1B48F1B746C148";
std::string sDec; // should end up with: "10187768649047767717933300899576725832"
我当前正在使用,它提供了一种非常简单的方法来实现此目的(但仅适用于GPL):
I'm currently using the c++ BigInt Class which offers a very easy way to achieve this (but is GPL only):
BigInt::Vin vbiTemp(sHex, 16);
sDec = vbiTemp.toStrDec();
有没有第三者算术库的简单转换方法吗?还是可以推荐具有类似简单性(效率无关紧要)的免费(非GPL)替代方案?
Is there simple way to do this conversion without a 3rd party arithmetic library? Or can you recommend a free (non-GPL) alternative with similar simplicity (efficiency is irrelevant)?
推荐答案
好,这是通用基本转换器类。我用C#编写了原始实现,现在将其转换为C ++。它的.NET起源可能仍然闪耀。
Ok, here is a generic base converter class. I wrote the original implementation in C#, and converted this now to C++. It's .NET origins may still shine through. Feel free to use it as you see fit.
您可以像这样使用它:
const BaseConverter& hex2dec = BaseConverter::HexToDecimalConverter();
std::cout << hex2dec.Convert("07AA17C660F3DD1D2A1B48F1B746C148");
输出将是:
10187768649047767717933300899576725832
该类不限于十六进制数字,但会
The class isn't limited to hex digits, but will happily translate between any base, using any base digit encoding.
-
BaseConverter :: BaseConverter (const std :: string& sourceBaseSet,const std :: string& targetBaseSet);
BaseConverter::BaseConverter(const std::string& sourceBaseSet, const std::string& targetBaseSet);
构造一个新的BaseConverter实例。该类将以 source 数基表示的数字转换为 target 数基。
Constructs a new BaseConverter instance. The class translates between numbers represented in a source number base to a target number base.
构造函数需要两个 string 参数指定用于源和目标数字基的符号。字符串中的第一个字符的值为 0 ,第二个字符的值为 1 ,依此类推。例如:八进制数基的符号通常为 01234567
,而十六进制的 0123456789ABCDEF
。任何可打印的ASCII字符都可用于符号,因此您可以使用例如。对于二进制系统,请使用 OI
(而不是 01
)。
The constructor takes two string arguments to specify the symbols to be used for the source and target number bases. The first character in the string has value 0, the 2nd has value 1, and so on. Example: the symbols for an octal number base are typically "01234567"
, and for hexadecimal "0123456789ABCDEF"
. Any printable ASCII character may be used for a symbol, so you could eg. use "OI"
(instead of "01"
) for a binary system.
注意:基本符号是区分大小写的,因此符号 0123456789abcdef
不会使用大写字符对十六进制数字进行解码。
Note: the base symbols are case sensitive, so the symbols "0123456789abcdef"
will not decode hexadecimal numbers using upper-case characters.
std :: string BaseConverter :: Convert (std :: string value)const;
std :: string BaseConverter :: Convert (const std :: string& value,size_t minDigits)const;
std::string BaseConverter::Convert(std::string value) const;
std::string BaseConverter::Convert(const std::string& value, size_t minDigits) const;
转换数字<$ c源数字库中的$ c> value 到目标数字库中,并返回结果。第二次重载使用附加参数 minDigits
来指定结果中的最小位数。返回的值将通过在目标数的基数前添加零个或多个值为 0 的符号来填充。
Converts number value
in the source number base into the target number base and returns the result. The 2nd overload takes an additional parameter minDigits
to specify the minimum number of digits in the result. The returned value will be padded by prepending zero or more symbols having value 0 in the target number base.
std :: string BaseConverter :: FromDecimal (无符号整数值)const;
std :: string BaseConverter :: FromDecimal (无符号整数值,size_t minDigits)const;
std::string BaseConverter::FromDecimal(unsigned int value) const;
std::string BaseConverter::FromDecimal(unsigned int value, size_t minDigits) const;
转换一个无符号整数十进制数到目标数的基数。
Converts an unsigned int decimal number to the target number base.
无符号整数 BaseConverter :: ToDecimal (std :: string value)const;
unsigned int BaseConverter::ToDecimal(std::string value) const;
将源编号系统中的数字转换为十进制 unsigned int 。 注意:如果源基本系统中数字的十进制值超过UINT_MAX,则结果将是错误的。
Converts a number in the source number system to a decimal unsigned int. Note: the result will be wrong if the decimal value of the number in the source base system exceeds UINT_MAX.
静态常量BaseConverter& BaseConverter :: DecimalToBinaryConverter ();
静态常量BaseConverter& BaseConverter :: BinaryToDecimalConverter ();
静态常量BaseConverter& BaseConverter :: DecimalToHexConverter ();
静态常量BaseConverter& BaseConverter :: HexToDecimalConverter ();
static const BaseConverter& BaseConverter::DecimalToBinaryConverter();
static const BaseConverter& BaseConverter::BinaryToDecimalConverter();
static const BaseConverter& BaseConverter::DecimalToHexConverter();
static const BaseConverter& BaseConverter::HexToDecimalConverter();
便捷函数返回 BaseConverter 适用于在通用数字基数之间进行转换。 注意:大写字母A-F用于十六进制数基。
Convenience functions returning instances of BaseConverter
suitable to convert between common number bases. Note: upper-case characters A - F are used for the hexadecimal number base.
// Arbitrary precision base conversion by Daniel Gehriger <[email protected]>
#include <string>
class BaseConverter
{
public:
std::string GetSourceBaseSet() const { return sourceBaseSet_; }
std::string GetTargetBaseSet() const { return targetBaseSet_; }
unsigned int GetSourceBase() const { return (unsigned int)sourceBaseSet_.length(); }
unsigned int GetTargetBase() const { return (unsigned int)targetBaseSet_.length(); }
/// <summary>
/// Constructor
/// </summary>
/// <param name="sourceBaseSet">Characters used for source base</param>
/// <param name="targetBaseSet">Characters used for target base</param>
BaseConverter(const std::string& sourceBaseSet, const std::string& targetBaseSet);
/// <summary>
/// Get a base converter for decimal to binary numbers
/// </summary>
static const BaseConverter& DecimalToBinaryConverter();
/// <summary>
/// Get a base converter for binary to decimal numbers
/// </summary>
static const BaseConverter& BinaryToDecimalConverter();
/// <summary>
/// Get a base converter for decimal to binary numbers
/// </summary>
static const BaseConverter& DecimalToHexConverter();
/// <summary>
/// Get a base converter for binary to decimal numbers
/// </summary>
static const BaseConverter& HexToDecimalConverter();
/// <summary>
/// Convert a value in the source number base to the target number base.
/// </summary>
/// <param name="value">Value in source number base.</param>
/// <returns>Value in target number base.</returns>
std::string Convert(std::string value) const;
/// <summary>
/// Convert a value in the source number base to the target number base.
/// </summary>
/// <param name="value">Value in source number base.</param>
/// <param name="minDigits">Minimum number of digits for returned value.</param>
/// <returns>Value in target number base.</returns>
std::string Convert(const std::string& value, size_t minDigits) const;
/// <summary>
/// Convert a decimal value to the target base.
/// </summary>
/// <param name="value">Decimal value.</param>
/// <returns>Result in target base.</returns>
std::string FromDecimal(unsigned int value) const;
/// <summary>
/// Convert a decimal value to the target base.
/// </summary>
/// <param name="value">Decimal value.</param>
/// <param name="minDigits">Minimum number of digits for returned value.</param>
/// <returns>Result in target base.</returns>
std::string FromDecimal(unsigned int value, size_t minDigits) const;
/// <summary>
/// Convert value in source base to decimal.
/// </summary>
/// <param name="value">Value in source base.</param>
/// <returns>Decimal value.</returns>
unsigned int ToDecimal(std::string value) const;
private:
/// <summary>
/// Divides x by y, and returns the quotient and remainder.
/// </summary>
/// <param name="baseDigits">Base digits for x and quotient.</param>
/// <param name="x">Numerator expressed in base digits; contains quotient, expressed in base digits, upon return.</param>
/// <param name="y">Denominator</param>
/// <returns>Remainder of x / y.</returns>
static unsigned int divide(const std::string& baseDigits,
std::string& x,
unsigned int y);
static unsigned int base2dec(const std::string& baseDigits,
const std::string& value);
static std::string dec2base(const std::string& baseDigits, unsigned int value);
private:
static const char* binarySet_;
static const char* decimalSet_;
static const char* hexSet_;
std::string sourceBaseSet_;
std::string targetBaseSet_;
};
BaseConverter.cpp:
BaseConverter.cpp:
// Arbitrary precision base conversion by Daniel Gehriger <[email protected]>
#include "BaseConverter.h"
#include <stdexcept>
#include <algorithm>
const char* BaseConverter::binarySet_ = "01";
const char* BaseConverter::decimalSet_ = "0123456789";
const char* BaseConverter::hexSet_ = "0123456789ABCDEF";
BaseConverter::BaseConverter(const std::string& sourceBaseSet, const std::string& targetBaseSet)
: sourceBaseSet_(sourceBaseSet)
, targetBaseSet_(targetBaseSet)
{
if (sourceBaseSet.empty() || targetBaseSet.empty())
throw std::invalid_argument("Invalid base character set");
}
const BaseConverter& BaseConverter::DecimalToBinaryConverter()
{
static const BaseConverter dec2bin(decimalSet_, binarySet_);
return dec2bin;
}
const BaseConverter& BaseConverter::BinaryToDecimalConverter()
{
static const BaseConverter bin2dec(binarySet_, decimalSet_);
return bin2dec;
}
const BaseConverter& BaseConverter::DecimalToHexConverter()
{
static const BaseConverter dec2hex(decimalSet_, hexSet_);
return dec2hex;
}
const BaseConverter& BaseConverter::HexToDecimalConverter()
{
static const BaseConverter hex2dec(hexSet_, decimalSet_);
return hex2dec;
}
std::string BaseConverter::Convert(std::string value) const
{
unsigned int numberBase = GetTargetBase();
std::string result;
do
{
unsigned int remainder = divide(sourceBaseSet_, value, numberBase);
result.push_back(targetBaseSet_[remainder]);
}
while (!value.empty() && !(value.length() == 1 && value[0] == sourceBaseSet_[0]));
std::reverse(result.begin(), result.end());
return result;
}
std::string BaseConverter::Convert(const std::string& value, size_t minDigits) const
{
std::string result = Convert(value);
if (result.length() < minDigits)
return std::string(minDigits - result.length(), targetBaseSet_[0]) + result;
else
return result;
}
std::string BaseConverter::FromDecimal(unsigned int value) const
{
return dec2base(targetBaseSet_, value);
}
std::string BaseConverter::FromDecimal(unsigned int value, size_t minDigits) const
{
std::string result = FromDecimal(value);
if (result.length() < minDigits)
return std::string(minDigits - result.length(), targetBaseSet_[0]) + result;
else
return result;
}
unsigned int BaseConverter::ToDecimal(std::string value) const
{
return base2dec(sourceBaseSet_, value);
}
unsigned int BaseConverter::divide(const std::string& baseDigits, std::string& x, unsigned int y)
{
std::string quotient;
size_t lenght = x.length();
for (size_t i = 0; i < lenght; ++i)
{
size_t j = i + 1 + x.length() - lenght;
if (x.length() < j)
break;
unsigned int value = base2dec(baseDigits, x.substr(0, j));
quotient.push_back(baseDigits[value / y]);
x = dec2base(baseDigits, value % y) + x.substr(j);
}
// calculate remainder
unsigned int remainder = base2dec(baseDigits, x);
// remove leading "zeros" from quotient and store in 'x'
size_t n = quotient.find_first_not_of(baseDigits[0]);
if (n != std::string::npos)
{
x = quotient.substr(n);
}
else
{
x.clear();
}
return remainder;
}
std::string BaseConverter::dec2base(const std::string& baseDigits, unsigned int value)
{
unsigned int numberBase = (unsigned int)baseDigits.length();
std::string result;
do
{
result.push_back(baseDigits[value % numberBase]);
value /= numberBase;
}
while (value > 0);
std::reverse(result.begin(), result.end());
return result;
}
unsigned int BaseConverter::base2dec(const std::string& baseDigits, const std::string& value)
{
unsigned int numberBase = (unsigned int)baseDigits.length();
unsigned int result = 0;
for (size_t i = 0; i < value.length(); ++i)
{
result *= numberBase;
int c = baseDigits.find(value[i]);
if (c == std::string::npos)
throw std::runtime_error("Invalid character");
result += (unsigned int)c;
}
return result;
}
这篇关于将大十六进制字符串转换为十进制字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!