Как я могу перебрать строку в 128-битных чанках?

У меня есть функция, которая работает с 128-битными блоками данных из строки произвольной длины. Если строка не делится поровну на 128 битов, она будет дополнена соответствующим образом.

Цель состоит в том, чтобы преобразовать данные в строку, которая подается в функцию.

Первоначально я думал о цикле через строку такой:

//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);
}

Я думаю, это сработает, но я думаю, что должен быть более элегантный способ сделать это. Одна мысль, которая пришла в голову, заключалась в том, чтобы заключить в капсулу strn в классе и реализовать свой собственный итератор, который может читать его содержимое в 128-битных порциях. Это привлекательно, потому что конструктор может обрабатывать отступы, а некоторые функции, которые я использую в настоящее время, могут быть приватными, что позволяет избежать потенциального неправильного использования. Это похоже на плодотворный подход? Если так, как можно реализовать свой собственный итератор? Подробные объяснения приветствуются, так как я очень неопытен в C ++.

Есть ли другие, возможно, лучшие подходы?

Спасибо!

6

Решение

Есть много подходов. Один из самых простых и простых будет выглядеть так:
Вы можете создать свой собственный тип размером 128 бит; просто struct сделаю работу.

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

И используйте это, чтобы перебрать вашу строку.
Приведите начало вашей строки к этому типу структуры:_128bit* start = (_128bit*)buffer; и начать итерацию с ним, используя арифметику интегрального указателя. Все операции на start будет работать с точки зрения его размера. Например. ,start++ переместится на 128 бит вперед; start-- переместится на 128 бит назад. Как только вы окажетесь в нужной позиции, переделайте ее в нужный тип и выполните ваши манипуляции.

3

Другие решения

Я, вероятно, сделал бы это с помощью итераторов, а не индексирования, все еще используя свой цикл 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);
}

Код boost :: iterator_adaptor будет выглядеть примерно так. Обратите внимание, что я получаю только четыре байта на блок вместо 16 для простоты в этом примере.

#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;
}
1

По вопросам рекламы [email protected]