Hex-String



  • Ich habe einen String der so aussieht:

    "AF2AF6AAFDAFAAAF3AFAAAF2AF6AAFDAFAAAF3AFAAAF2AF6AAFDAFAAAF3AFAA"

    Ich möchte dass die 2 Zeichen in 1 Byte gespeichert werden.
    itoa wäre eine Lösung, nur ist sie nicht im Standard drin.

    Gäbe es da eine standard-Methode, boost wäre auch willkommen!



  • Das ist in diesem speziellen Fall schwierig, weil der String eine ungerade Anzahl Zeichen enthält.

    Ansonsten ist so was aber recht einfach zusammenzuschustern:

    #include <iostream>
    #include <string>
    #include <stdexcept>
    
    unsigned char hex_value(char c) {
      if(c >= '0' && c <= '9') return c - '0';
      if(c >= 'A' && c <= 'Z') return c - 'A' + 10;
      if(c >= 'a' && c <= 'z') return c - 'a' + 10;
    
      throw std::invalid_argument("Ungültiges Hex-Zeichen");
    }
    
    std::string parse_hexstring(std::string const &input) {
      if(input.size() % 2 != 0) throw std::invalid_argument("Ungerade Anzahl Zeichen im Hex-String");
    
      std::string result;
    
      result.reserve(input.size() / 2);
    
      for(std::string::size_type i = 0; i < input.size(); i += 2) {
        result.push_back(static_cast<char>(hex_value(input[i]) * 16 + hex_value(input[i + 1])));
      }
    
      return result;
    }
    



  • Mod

    Viel kompliziertes drumherum, dafür wird das eigentliche Lesen sehr elegant:

    #include <streambuf> 
    #include <sstream>
    #include <iostream>
    
    class seppjs_zerhacker_streambuf : public std::streambuf
    {
    public:
      seppjs_zerhacker_streambuf(std::istream& in )
        : in(in) 
        , buf (in.rdbuf())
        , counter(0)
      {
        in.rdbuf(this); 
      }
      ~seppjs_zerhacker_streambuf()
      {
        in.rdbuf(buf); 
      }
    
    protected:
      virtual int_type underflow() 
      {
        if (counter != 2)
          return buf->sgetc();
        else
          return traits_type::to_int_type(' ');
      }
      virtual int_type uflow()      
      {
        if (counter!=2)
          {
            ++counter;
            return buf->sbumpc();
          }
        else
          {
            counter = 0;
            return traits_type::to_int_type(' ');
          }
      }
    private:
      seppjs_zerhacker_streambuf( const seppjs_zerhacker_streambuf& );  
      seppjs_zerhacker_streambuf& operator=( const  seppjs_zerhacker_streambuf& ); 
      std::istream& in;
      std::streambuf* buf;
      short counter;
    };
    
    int main()
    {
      std::stringstream in("AF2AF6AAFDAFAAAF3AFAAAF2AF6AAFDAFAAAF3AFAAAF2AF6AAFDAFAAAF3AFAA");
      seppjs_zerhacker_streambuf foo(in);
    
      short byte;
      while (in >> std::hex >> byte)
        std::cout << "Gelesen: " << byte << '\n';
    }
    

    Kann auch sehr leicht angepasst werden, so dass der Puffer nach einer wählbaren Anzahl Zeichen zerhackt, falls man mal mit Words statt Bytes arbeiten möchte.


Anmelden zum Antworten