2017-06-06 2 views
1

Based on this code here, konnte ich einen Code schreiben, der einen Vektor von Ganzzahlen in eine Base64-codierte Version konvertiert. Und ich kann bestätigen, dass es die richtige Ausgabe ist, wenn ich mit einer separaten Java-Implementierung vergleiche.C++ 11 Boost, wie Base64 entschlüsseln zurück zu Integer-Präsentation

#include <iostream> 
#include <iomanip> 
#include <cstdlib> 
#include <fstream> 
#include <iostream> 
#include <cstdint> 
#include <typeinfo> 

#include <boost/program_options.hpp> 
#include <boost/filesystem.hpp> 
#include <boost/archive/iterators/base64_from_binary.hpp> 
#include <boost/archive/iterators/binary_from_base64.hpp> 
#include <boost/archive/iterators/transform_width.hpp> 
#include <boost/archive/iterators/ostream_iterator.hpp> 
#include <boost/archive/iterators/remove_whitespace.hpp> 

///.... 

using namespace std; 
namespace po = boost::program_options; 
namespace fs = boost::filesystem; 
namespace bi = boost::archive::iterators; 

    std::stringstream os; 
    typedef 
     bi::base64_from_binary< // convert binary values to base64 characters 
      bi::transform_width< // retrieve 6 bit integers from a sequence of 32 bit ints 
       vector<int32_t>::const_iterator, 
       6, 
       32 
      > 
     > 
     base64_text; 

    copy(
     base64_text(di.cbegin()), 
     base64_text(di.cend()), 
     ostream_iterator<char>(os) 
     ); 

    cout << os.str() << "\n"; 

Jetzt versuche ich, den Code zu schreiben, um diese wieder in einen Vektor von ganzen Zahlen zu entschlüsseln, aber dies viel schwieriger erweist. Ich habe versucht, die gegebenen Beispiele in meinen Anwendungsfall zu konvertieren (siehe unten), aber ich bekomme nur einen nicht hilfreichen Fehler beim Kopieraufruf. Frustrierend, alles, was ich finde, Annahme String Eingabe/Ausgabe zu kodieren/zu decodieren. Jede Hilfe wird geschätzt.

typedef 
    bi::transform_width< 
    bi::binary_from_base64<bi::remove_whitespace<string::const_iterator>>, 
     32, 6 
    > 
    base64_dec; 

    vector<int32_t> decoded_ints; 
    copy(
     base64_dec(base64ints.cbegin()), 
     base64_dec(base64ints.cend()), 
     decoded_ints.begin() 
     ); 
+0

immer bietet komplette, minimal, Arbeiten (Arbeiten nicht in Ihrem Fall) Beispiel kontaktieren – kreuzerkrieg

Antwort

0

Sie versuchen, in einem leeren Vektor zu kopieren, copy nicht kümmert das Einsetzen Elements, sondern nur Kopien. Sie haben die Zielvektor mit resize() oder nur back_inserter wie diese

vector<int32_t> decoded_ints; 
    copy(
     base64_dec(base64ints.cbegin()), 
     base64_dec(base64ints.cend()), 
     std::back_inserter(decoded_ints) 
     ); 

EDIT001

verwenden vorzubelegen: Da gibt es keine bessere Antwort gegeben wird und trotz minimaler Arbeitsbeispiel wasnt eingeführt und ich habe keine Ahnung, warum es segfault bekommt werde ich Erweitern Sie meine Antwort.
Above Code sollte, so gut funktionieren wie Ihre int vector initialisiert, wenn es erklärt wird - so etwas wie vector<int32_t> decoded_ints(base64_dec(base64ints.cbegin()),base64_dec(base64ints.cend())) jedoch Ihre gesamte Code nicht funktioniert, nur knapp sein Ziel überprüfen, ob es die Daten korrekt kodiert, aber es ist definitiv das richtige Ergebnis doesnt produzieren bei der Decodierung. Sieht aus wie transform_width tut nicht den Trick mit etwas breiter als 8 Bits oder es ist eine Auffüllung der codierten Daten hinzugefügt, die bei der Decodierung berücksichtigt werden sollte. In jedem Fall könnten Sie all diese umgehen, indem Sie Ihren int-Vektor in eine Zeichenfolge (oder einen Vektor von int8_t) schieben. Etwas wie das.

#include <boost/archive/iterators/base64_from_binary.hpp> 
#include <boost/archive/iterators/binary_from_base64.hpp> 
#include <boost/archive/iterators/transform_width.hpp> 
#include <vector> 
#include <iostream> 
#include <memory.h> 

int main() 
{ 
    using namespace std; 
    namespace bi = boost::archive::iterators; 

    using IntVec = vector<int32_t>; 
    IntVec di(1024, 0); 

    int32_t n = 0; 
    std::generate(di.begin(), di.end(), [&n]() { return n++; }); 

    string input(reinterpret_cast<string::pointer>(di.data()), 
       reinterpret_cast<string::pointer>(di.data()) + (di.size() * sizeof(IntVec::value_type))); 
    typedef bi::base64_from_binary<bi::transform_width<string::const_iterator, 6, 8>> base64_text; 
    typedef bi::transform_width<bi::binary_from_base64<string::const_iterator>, 8, 6> base64_dec; 

    std::string base64ints(base64_text(input.cbegin()), base64_text(input.cend())); 
    string decoded(base64_dec(base64ints.begin()), base64_dec(base64ints.end())); 
    IntVec decoded_ints(reinterpret_cast<IntVec::const_pointer>(decoded.data()), 
         reinterpret_cast<IntVec::const_pointer>(decoded.data()) + 
          (decoded.size()/sizeof(IntVec::value_type))); 

    if (decoded_ints.size() == di.size()) 
     cout << "Size matches" << std::endl; 
    else 
     cout << "Size does not match" << std::endl; 

    if (memcmp(decoded_ints.data(), di.data(), di.size() * sizeof(int32_t)) == 0) 
     cout << "Data matches" << std::endl; 
    else 
     cout << "Data does not match" << std::endl; 
} 

Live on CoLiRu
Außerdem halte ich es für eine gute Idee ist Robert Ramey (Boost-Serialisierung Maintainer) auf Boost Mailing List

+0

Dadurch wird der zuvor aufgetretene Segfault vermieden, jedoch nicht die korrekte Ausgabe. Das heißt, die zurückgegebenen Eingaben sind nicht dieselben wie die ursprünglichen Eingaben, die dekodiert wurden. Dies ist für mich leicht zu überprüfen, da in meinem Anwendungsfall alle Ints in einer sortierten Reihenfolge sind. –