[英]How do I convert a base64 string to hexadecimal string in C++?
我有一個表示base64中值的字符串。 我想將此字符串從base64轉換為十六進制。 我正在Ubuntu 10.10上使用C ++進行工作。 我有以下代碼:
std::string ssir = "DNQwSinfOUSSWd+U04r23A==";
std::string dec=(base64_decode(ssir));
std::stringstream ss;
for (int i=0; i<dec.size(); ++i) {
if (i != 0) ss << ':';
ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<unsigned int>(dec[i]);//(int)(dec[i]);
}
std::string res;
res= ss.str();
cout<<"the ress is: "<<res<<std::endl;
結果是:
0C:ffffffd4:30:4A:29:ffffffdf:39:44:ffffff92:59:ffffffdf:ffffff94:ffffffd3:ffffff8a:fffffff6:ffffffdc
除了那些ffffffff,它是正確的。 我該怎么做才能解決此問題? 如果我想將十六進制結果寫入std::vector<unsigned char> x
,該怎么辦?
嘗試使用此強制轉換:
static_cast<unsigned char>(dec[i])
int
是32位寬,您只想輸出8位,這就是char
寬度。 在格式化數字時,大概std::hex
正在考慮輸入類型。 (盡管我不確定符號擴展名來自何處,因為您正在轉換為無符號類型...)
@cdhowie的帖子幾乎正確。 但是,如果強制轉換為char
(有符號或無符號),則標准流運算符將嘗試寫出該字符的ASCII值。 您將需要另一個強制轉換:
static_cast<int>(static_cast<unsigned char>(dec[i]))
或顯式截斷值:
(static_cast<int>(dec[i]) & 0xFF)
(在兩種情況下,都不需要對外部int
進行unsigned
;在第一種情況下, signed int
足夠寬,可以容納所有unsigned char
值;在第二種情況下,您將使該值顯式為正。)
您可以嘗試其他字符串到十六進制的轉換方法。 我寫了兩個函數。 str_to_hex-是我的方法。 str_to_hex2-是您的。 我省略了base64編碼。 然后我調用了1M次函數和您的函數。 str_to_hex的執行時間為
time ./a.out
real 0m0.365s
user 0m0.360s
sys 0m0.010s
並且str_to_hex2的執行時間為:
time ./a.out
real 0m3.253s
user 0m3.220s
sys 0m0.000s
Ubuntu 10.04、64位,g ++ 4.4.3,-O3選項。
測試程序的代碼如下。
#include <string>
#include <iostream>
#include <sstream>
#include <iomanip>
void str_to_hex() {
std::string ssir = "DNQwSinfOUSSWd+U04r23A==";
static const char *hex = "0123456789ABCDEF";
std::string result;
result.reserve(ssir.size() * 3);
for (std::string::const_iterator i = ssir.begin(), end = ssir.end(); i != end; ++i) {
if (i != ssir.begin())
result.push_back(':');
result.push_back(hex[*i >> 4]);
result.push_back(hex[*i & 0xf]);
}
}
void str_to_hex2() {
std::string ssir = "DNQwSinfOUSSWd+U04r23A==";
std::stringstream ss;
for (int i=0; i<ssir.size(); ++i) {
if (i != 0) ss << ':';
ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<unsigned int>(ssir[i] & 0xff);
}
}
int main() {
for (int i = 0; i < 1000000; ++i)
str_to_hex();
}
我不確定這是否是最好的解決方案,但這就是我的方法。
#include <vector>
#include <bitset>
#include <string>
//hex->dec->bin8->bin6->dec->base64table
//HexToDec
unsigned int HexToDec(std::string hexInput)
{
//initlize variables
const int HexBaseASCCI = 48;
const int HexBase = 16;
size_t hexCharPlace = hexInput.size() -1;
int result = 0;
//reading the hexInput
for (int i = 0; i < hexInput.size(); i++)
{
char hexChar = hexInput.at(i);
int dec = 0;
//Finde the equvilcey of the char hex u read from the HexNum string
if (hexChar>='0' && hexChar<='9'){dec = (int)hexChar - HexBaseASCCI;}
else
{ switch (hexChar)
{ case ('A') :
case ('a') : {dec = 10; break;}
case ('B') :
case ('b') : {dec = 11; break;}
case ('C') :
case ('c') : {dec = 12; break;}
case ('D') :
case ('d') : {dec = 13; break;}
case ('E') :
case ('e') : {dec = 14; break;}
case ('F') :
case ('f') : {dec = 15; break;}
case ('X') :
case ('x') : {dec = 0; break;}
default : {
std::string msg ("is not in hex format");
throw std::logic_error(msg);};
}
}
//calculating the final dec
result += dec * pow(HexBase,hexCharPlace);
hexCharPlace--;
}
return result;
}
//HexToDec vector version
std::vector<unsigned int> HexToDec(std::vector<std::string> hex)
{
std::vector<unsigned int> dec;
for( auto x : hex){
dec.push_back(HexToDec(x));
}
return dec;
}
//BreakHexStringIntoGroups TODO .. needs to imporve
std::vector<std::string> BreakHexStringIntoGroups(std::string hexInput, unsigned long lengthOfBreaks)
{
std::vector<std::string> hexGroups;
if(!(hexInput.size() % 2)){
for (auto index(0); index < hexInput.size(); index+=lengthOfBreaks )
{
hexGroups.push_back(hexInput.substr(index,lengthOfBreaks));
}
}
else
{
for (auto index(0); index < hexInput.size()-1; index+=lengthOfBreaks )
{
hexGroups.push_back(hexInput.substr(index,lengthOfBreaks));
}
hexGroups.push_back(hexInput.substr(hexInput.size()-1));
}
return hexGroups;
}
//DecTo8BitsBin
std::vector<std::string> DecTo8BitsBin(std::vector<unsigned int> dec)
{
std::vector<std::string> bin;
for (auto x: dec)
{
bin.push_back(std::bitset<8>(x).to_string());
}
return bin;
}
//FuseStringVector
std::string FuseStringVector(std::vector<std::string> vec)
{
std::string res;
for (auto str: vec)
{
res+=str;
}
return res;
}
//BreakBinStringInto6BitsGroups TODO .. needs to imporve
std::vector<std::string> BreakBinStringInto6BitsGroups(std::string longBin){
std::vector<std::string> res;
if (!(longBin.size() % 6))
{
for (unsigned int i(0) ; i < longBin.size(); i+=6){
res.push_back(longBin.substr(i,6));
}
}
else
{
unsigned int max6AlignedIndex = (longBin.size() / 6)*6;
unsigned int paddingZeros = 6 -(longBin.size() % 6);
for (unsigned int i(0) ; i < max6AlignedIndex; i+=6){
res.push_back(longBin.substr(i,6));
}
res.push_back(longBin.substr(max6AlignedIndex) + std::string(paddingZeros, '0'));
}
return res;
}
//Bin6BitsToDec
unsigned int Bin6BitsToDec(std::string bin6Bit){
unsigned int decimalNumber(0), i(0), remainder(0);
unsigned int n (std::stoi(bin6Bit));
while (n!=0)
{
remainder = n%10;
n /= 10;
decimalNumber += remainder*pow(2,i);
++i;
}
return decimalNumber;
}
//Bin6BitsToDec vector
std::vector<unsigned int> Bin6BitsToDec(std::vector<std::string> bin6Bits)
{
std::vector<unsigned int> dec;
for(auto bin: bin6Bits)
{
dec.push_back(Bin6BitsToDec(bin));
}
return dec;
}
//DecToBase64
std::vector<char> DecToBase64(std::vector<unsigned int> dec)
{
const std::string base64Table("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
std::vector<char> res;
for(auto x: dec)
{
res.push_back(base64Table.at(x));
}
return res;
}
//FuseCharVector
std::string FuseCharVector(std::vector<char> vec)
{
return std::string(vec.begin(), vec.end());
}
std::string HexToBase64(std::string hex){
std::vector<std::string> brokenHexGroups(BreakHexStringIntoGroups(hex,2));
std::vector<unsigned int> brokenHexGroupsInDec(HexToDec(brokenHexGroups));
std::vector<std::string> bin8bits= DecTo8BitsBin(brokenHexGroupsInDec);
std::string fusedBin8bits = FuseStringVector(bin8bits);
std::vector<std::string> bin6Bits = BreakBinStringInto6BitsGroups(fusedBin8bits);
std::vector<unsigned int> bin6BitsInDec(Bin6BitsToDec(bin6Bits));
std::vector<char> decToBase64Chars = DecToBase64(bin6BitsInDec);
std::string finalString = FuseCharVector(decToBase64Chars);
return finalString;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.