Увеличение отдельных символов в строке

#c #string

#c #строка

Вопрос:

Я не знаю, правильный ли у меня tiltle для этого, поэтому, пожалуйста, поправьте меня, если я ошибаюсь, и я изменю свое название.

У меня есть строка, для этого примера я буду использовать:

 "8ce4b16b"
  

Я хотел бы сдвинуть биты (я думаю) вдоль 1, чтобы строка была:

 "9df5c27c"
  

Есть идеи?

Редактировать:

Просто чтобы вы знали, эти строки являются шестнадцатеричными. Таким образом, он никогда не достигнет z . Все, что я хочу сделать, это добавить число к числам и выполнить один шаг по алфавиту, так что a-> b, f-> g и т.д. и т.д.

Если число равно 9, то будет условие сохранить его равным 9.

Вывод НЕ обязательно должен быть шестнадцатеричным.

Также строка является только примером. Это часть шифрования MD5.

Комментарии:

1. В указанном примере вы не сдвигаете никаких битов, вы просто добавляете 1 к каждому шестнадцатеричному (я полагаю) числу в строке.

2. Я не понимаю пример. Каждый символ сопоставляется следующему, кроме ‘4’? Что должно произойти с ‘9’, ‘Z’ или unsigned char(255) ?

3. @Peter G.: Я предполагаю, что 4 было опечаткой. Я изменил его на 5.

4. Ваша правка не имеет смысла. Если это шестнадцатеричные строки, F никогда не должно становиться G, а 9 всегда должно становиться A при добавлении 1.

5. Схема шифрования, которая шифрует как «8», так и «9» как «9», будет иметь некоторые незначительные проблемы с расшифровкой.

Ответ №1:

Преобразовать string ? Это звучит как работа для std::transform() :

 #include <cassert>
#include <string>

char increment(char c)
{
    if ('9' == c)
    {
        return '9';
    }
    return   c;
}

std::string increment_string(const std::stringamp; in)
{
    std::string out;
    std::transform(in.begin(), in.end(), std::back_inserter(out), increment);
    return out;
}

int main()
{
    assert(increment_string("8ce4b16b") == "9df5c27c");
    assert(increment_string("ffffffff") == "gggggggg");
    assert(increment_string("89898989") == "99999999"); // N.B: this is one of 2^8 strings that will return "99999999"
    assert(increment_string("99999999") == "99999999"); // This is one more. Mapping backwards is going to be tricky!
    return 1;
}
  

Любые ограничения, которые вы хотите наложить на символы, могут быть реализованы в increment() функции, как показано.

Если, с другой стороны, вы хотите обработать строку как шестнадцатеричное число и добавить к нему 0x11111111 :

 #include <sstream>
#include <cassert>

int main()
{
    std::istringstream iss("8ce4b16b");
    long int i;
    iss >> std::hex >> i;
    i  = 0x11111111;
    std::ostringstream oss;
    oss << std::hex << i;
    assert(oss.str() == "9df5c27c");
    return 1;
}
  

При построении этого не было сдвинуто ни одного бита string .

Ответ №2:

Похоже, вы просто добавили 0x11111111 к целому числу. Но можете ли вы точно указать, что именно вы вводите? И каким должен быть результат, когда вы добавляете единицу к «f» или «9»?

Комментарии:

1. Да, это действительно зависит от того, хотите ли вы удвоить «шестнадцатеричное число» или просто увеличить значения char в алфавитном порядке. В вашем примере нет никаких 9 или F!

Ответ №3:

Это не смещение битов … сдвиг бита умножает значение слова на 2. Вы просто увеличиваете каждое шестнадцатеричное значение на 1, и это можно сделать, добавив 0x11111111 к вашему dword.

Например, если бы вы взяли свое значение 0x8ce4b16b (это означало бы обработку значений, которые вы напечатали выше, как если бы они были 4-байтовым двойным словом в шестнадцатеричном формате), сдвинув его на один бит, вы получили бы 0x19C962D6 .

Но если вы просто хотите увеличить каждый фрагмент вашего dword (каждое отдельное значение в шестнадцатеричном числе представляет собой 4 бита или фрагмент), вам придется добавить смещение 0x1 к каждому фрагменту. Также в шестнадцатеричном слове нет значения G … у вас есть значения 0->9 , а затем A->F , где F представляет базовое значение 10 15. Наконец, когда вы добавляете 0x1 в 0xF , вы собираетесь обернуть вокруг 0x0 .

Ответ №4:

Вы имеете в виду, что хотите увеличить каждый символ в строке? Вы можете сделать это, выполнив итерацию по массиву и добавив по одному к каждому символу.

Комментарии:

1. Итак, я перебираю каждый элемент в строке и добавляю 1? Будет ли это работать и с символами?

2. Нет, это не так просто, как это. Предположительно, символ представляет собой шестнадцатеричное значение, поэтому добавление 1 к f возвращает g — что неверно или добавление 1 к 9 — не даст вам a ! Вам нужно правильно обрабатывать приращение…

3. @Nim вывод не должен быть недоступным для чтения шестнадцатеричным. Итак, ‘g’ — это нормально. У меня будет условие сохранить 9 как 9. Итак, все, что я делаю, это создаю m_string[i] = 1; ?