2011-01-14 246 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; 
} 
相關問題