好的,这是一个通用的进制转换器类。我最初在C#中编写了原始实现,并将其转换为了C++。它仍然具有.NET的特点。随意使用它。
您可以像这样使用它:
const BaseConverter& hex2dec = BaseConverter::HexToDecimalConverter()
std::cout << hex2dec.Convert("07AA17C660F3DD1D2A1B48F1B746C148")
输出将会是:
10187768649047767717933300899576725832
该类不仅局限于十六进制数字,而是可以使用任何进制和任何基本数字编码之间进行转换。
API
BaseConverter::BaseConverter(const std::string& sourceBaseSet, const std::string& targetBaseSet);
构造一个新的 BaseConverter 实例。该类可实现在源数字系统和目标数字系统之间的数字转换。
构造函数有两个参数,均为 string 类型,用于指定源和目标数字系统的符号。字符串中第一个字符的值为 0,第二个字符的值为 1,以此类推。例如,八进制数字系统的符号通常为 "01234567"
,十六进制数字系统的符号为 "0123456789ABCDEF"
。您可以使用任何可打印的 ASCII 字符作为符号,因此您可以将 "OI"
(而不是 "01"
)用于二进制系统。
注意:基础符号是区分大小写的,因此符号"0123456789abcdef"
不能解码使用大写字母表示的十六进制数。
std::string BaseConverter::Convert(std::string value) const;
std::string BaseConverter::Convert(const std::string& value, size_t minDigits) const;
将源数字系统中的数字value
转换为目标数字系统中的数字并返回结果。第二个重载接受额外的参数minDigits
,用于指定结果中数字的最小位数。返回值将通过在目标数字系统中前置零或多个值为0的符号进行填充。
std::string BaseConverter::FromDecimal(unsigned int value) const;
std::string BaseConverter::FromDecimal(unsigned int value, size_t minDigits) const;
将unsigned int类型的十进制数字转换为目标数字系统中的数字。
unsigned int BaseConverter::ToDecimal(std::string value) const;
将源数字系统中的数字转换为十进制的unsigned int类型。 注意:如果源数字系统中的数字的十进制值超过UINT_MAX,则结果将不正确。
static const BaseConverter& BaseConverter::DecimalToBinaryConverter();
static const BaseConverter& BaseConverter::BinaryToDecimalConverter();
static const BaseConverter& BaseConverter::DecimalToHexConverter();
static const BaseConverter& BaseConverter::HexToDecimalConverter();
这些函数是方便的函数,返回适合于在常见数字进制之间进行转换的BaseConverter
实例。注意:十六进制数使用大写字母A到F。
BaseConverter.h:
#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(); }
BaseConverter(const std::string& sourceBaseSet, const std::string& targetBaseSet);
static const BaseConverter& DecimalToBinaryConverter();
static const BaseConverter& BinaryToDecimalConverter();
static const BaseConverter& DecimalToHexConverter();
static const BaseConverter& HexToDecimalConverter();
std::string Convert(std::string value) const;
std::string Convert(const std::string& value, size_t minDigits) const;
std::string FromDecimal(unsigned int value) const;
std::string FromDecimal(unsigned int value, size_t minDigits) const;
unsigned int ToDecimal(std::string value) const;
private:
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:
#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);
}
unsigned int remainder = base2dec(baseDigits, 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;
}