2012-11-06 5 views
5

Ho una funzione che opera su blocchi di dati a 128 bit da una stringa di lunghezza arbitraria. Se la stringa non è equamente divisibile in blocchi di 128 bit, verrà riempita di conseguenza.Come posso scorrere su una stringa in blocchi di 128 bit?

Lo scopo è trasformare i dati nella stringa inserita nella funzione.

inizialmente ho pensato di loop attraverso la stringa tale:

//This might have stupid errors. Hopefully it stillg gets the point across. 
for (int i = 0; i < strn.size(); i += 16) 
{ 
    string block = strn.substr(i, i + 15); 
    strn.replace(i, i + 15, block); 
} 

Credo che questo avrebbe funzionato, ma sto pensando ci deve essere un modo più elegante per fare questo. Un'idea che mi è venuta in mente era incapsulare strn in una classe e implementare il mio iteratore in grado di leggere il suo contenuto in blocchi di 128 bit. Questo è interessante perché il costruttore potrebbe gestire il padding e alcune delle funzioni che uso attualmente potrebbero essere rese private, evitando così possibili abusi. Questo sembra un approccio fruttuoso? In tal caso, come si fa a implementare il proprio iteratore? Le spiegazioni dettagliate sono le benvenute, dato che sono molto inesperto del C++.

Ci sono altri approcci, forse migliori?

Grazie!

risposta

3

Ci sono molti approcci. Uno dei più semplici e diretti sarebbe così: è possibile creare il proprio tipo di dimensioni esattamente 128 bit; semplice struct farà il lavoro.

typedef struct 
{ 
    char buf[16]; 
} _128bit; 

E usarlo per scorrere la stringa. Lancia l'inizio della stringa a questo tipo di struct: _128bit* start = (_128bit*)buffer; e inizia a scorrere con esso, utilizzando l'aritmetica del puntatore integrale. Tutte le operazioni su start funzioneranno in termini di dimensioni. Per esempio. , start++ si sposterà a 128 bit in avanti; start-- si sposterà a 128 bit indietro. Una volta che sei nella posizione desiderata, rielaboralo nel tipo desiderato ed esegui le tue manipolazioni.

+0

Sembra un approccio semplice ed elegante! Solo alcune domande: 1) C'è una ragione per il carattere di sottolineatura in '_128bit'? 2) Perché il typedef? Immagino che questo mi permetta di lanciare altre variabili e costanti come il suo tipo ... la mia inuizione è corretta? 3) Com'è che l'operatore '++' è già sovraccarico in questo esempio? Perché non devo farlo esplicitamente? Mille grazie e molte scuse per la mia ignoranza sui migliori costrutti C++! =) – blz

+1

1. Se ricordo correttamente, i nomi delle variabili non possono iniziare con una cifra. 2. Hmm, non serve in realtà in C++, in C questo può ridurre il codice :). 3. Questo è il vantaggio dell'aritmetica del puntatore, opera in termini di elementi puntati, vedere qui per maggiori dettagli: http://stackoverflow.com/questions/394767/pointer-arithmetic BTW, questa è una soluzione C pura, senza C++ caratteristiche utilizzate – SomeWittyUsername

+0

Ok questo ha senso. Comunque, sono ancora un po 'incerto sul bit dei typedef. La parola chiave 'typedef' non ti consente di creare un nuovo nome tipo? In quanto tale, il tuo esempio non dovrebbe specificare un nome per la struttura che hai definito? ... qualcosa come 'typedef struct {...}'? – blz

1

avrei probabilmente farlo con iteratori invece di indicizzazione, ancora utilizzando il proprio ciclo for:

const int NUM_BITS_IN_CHUNK = 128; 
const int CHUNK_SIZE = NUM_BITS_IN_CHUNK/CHAR_BIT; 

for(std::string::const_iterator iter = str.begin(); iter < str.end(); iter += CHUNK_SIZE) 
{ 
    your_func(iter, iter + CHUNK_SIZE); 
} 

Il codice boost :: iterator_adaptor sarebbe simile a questa. Si noti che sto ottenendo solo quattro byte per blocco invece di 16 per semplicità nell'esempio .:

#include <iostream> 
#include <string> 

#include <boost/iterator_adaptors.hpp> 

struct string_chunk_iterator : public boost::iterator_adaptor<string_chunk_iterator, std::string::const_iterator> 
{ 
    string_chunk_iterator(const std::string::const_iterator& base) : iterator_adaptor(base) { } 

private: 
    friend class boost::iterator_core_access; 
    void increment() { this->base_reference() = this->base() + 4; } 
    void advance(typename iterator_adaptor::difference_type n) 
    { 
     this->base_reference() = this->base() + (4 * n); 
    } 
}; 

int main() 
{ 
    const std::string tester(20, 'A'); 

    string_chunk_iterator iter(tester.begin()); 
    string_chunk_iterator str_end(tester.end()); 

    for(; iter != str_end; ++iter) 
    { 
     std::string chunk(&*iter, &*(iter + 1)); 

     std::cout << chunk << std::endl; 
    } 

    return 0; 
} 
+0

C'è un modo per sottoclasse 'std :: string :: const_iterator' tale che incrementandolo con' ++ 'o chiamando' iter.next() 'aumenterà di 128 bit? Inoltre, sono un po 'confuso. Avrei pensato che 'iter + = 128' avrebbe spostato il puntatore 128 * byte * (o indici). Cosa mi manca? – blz

+1

@blz Credo che si possa usare 'boost :: iterator_adapter' per creare un tale iteratore, ma ho poca esperienza con quella parte di boost. Hai ragione che 'iter + = 128' aumenterebbe di 128 byte. Fortunatamente, non è quello che sto facendo nel mio codice: sto aumentando di 16 (byte). Ecco perché ho creato le costanti, per assicurarmi che funzioni ancora anche su un sistema con 'char' a 16 bit. –

Problemi correlati