2011-01-14 248 views
2

我有一个字符串,代表base64中的值。我想将此字符串从base64转换为十六进制。我在Ubuntu 10.10上使用C++。我有以下代码:如何将base64字符串转换为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,我该怎么做?

+2

请注意,你称之为“hexa结果”是一个字符串,因此将它存储在`std :: string`中会更有意义。 – ereOn 2011-01-14 08:17:58

+0

重复(昨天是同一个用户):[base 64 string to hexa string](http://stackoverflow.com/questions/4680441/base-64-string-to-hexa-string) – 2011-01-14 08:32:26

回答

2

尝试使用该模具来代替:

static_cast<unsigned char>(dec[i]) 

int为32个位宽,你只需要输出8位,这是char有多宽。假定std::hex在格式化数字时正在考虑输入类型。 (尽管我不太确定标志扩展名是从哪里来的,因为您正在转换为无符号类型......)

2

@cdhowie的帖子几乎是正确的。但是,如果您转换为char(有符号或无符号),则标准流操作符将尝试写出该字符的ASCII值。你要么需要另投:

static_cast<int>(static_cast<unsigned char>(dec[i])) 

或明确截断值:

(static_cast<int>(dec[i]) & 0xFF) 

(在这两种情况下,你的外int并不需要是unsigned,在第一种情况下,signed int是足够宽以容纳所有unsigned char值,而在第二个中,您明确地将该值设为正值。)

2

您可以尝试另一个字符串到十六进制的转换方法。我写了两个函数。 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位,克++ 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 = "ABCDEF"; 
    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(); 

} 
0

我不确定这是否是最好的解决方案,但这是我做到的。

#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("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/"); 
    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; 
} 
相关问题