Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
танкист34
-62 / 0 / 0
Регистрация: 15.03.2013
Сообщений: 328
#1

Битовые операции, найти ошибку в коде - C++

13.03.2014, 12:47. Просмотров 885. Ответов 31
Метки нет (Все метки)

Написал немного коду с битовыми операциями, чтобы заменять биты, но почему то работает не так как хотелось. Комментарии все в коде. В HEX редакторе получаются в основном одни FF, т.е. байты заполненные единичками. Алгоритм должен быть обратным, но не выходит.
key это интовская переменная
array это байтовый массив содержащих исходные данные (QByteArray array)
itog это байтовый массив измененных данных

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
void MainWindow::sh(int n)
{
 
int razr_0 = 1, razr_1 = 2, razr_3 = 8, razr_4 = 16; //для проверки значения тех разърядов которые подлжеат XOR
 
for(int i = 0; i < 8; i++) {
 
    int razr0 = razr_0 & key; //проверяем значения бит нужных разърядов
    int razr1 = razr_1 & key;
    int razr3 = razr_3 & key;
    int razr4 = razr_4 & key;
 
        int mlad_bit = razr_0 & array[n]; //младший бит элемента массива из файла
        array[n] = array[n] >> 1; //сдвигаем вправо, чтобы на следующем шаге опять проверять младший бит
 
        int nov_bit = razr4 ^ razr3 ^ razr1 ^ razr0;
        if(nov_bit == 1)
        {
            //получаем новый бит == 1
            key = key >> 1; //удаляем младший бит
            key = key | 2048; //добавляем старший разъряд
        }
        else
        {
            //получаем новый бит == 0
            key = key >> 1; //удаляем младший бит
        }
 
 
        //********************************************************************************
        int nov_kod_bit = mlad_bit ^ razr0;
        if(nov_kod_bit == 0)
        {
            itog[n] = itog[n] | 0;
            itog[n] = itog[n] >> 1;
        }
        else
        {
            itog[n] = itog[n] | 128;
            itog[n] = itog[n] >> 1;
        }
 
 
 
    }
}
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.03.2014, 12:47
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Битовые операции, найти ошибку в коде (C++):

Арифметические операции, найти ошибку в коде - C++
Где ошыбка? #include &lt;iostream&gt; #include &lt;iomanip&gt; using namespace std; int main() { double mult = 1; int n = 1; ...

Как представлять двоичные числа в обратном и дополнительном коде, используя битовые операции? - C++
#include &lt;iostream&gt; #include &lt;string&gt; #include &lt;algorithm&gt; using namespace std; int main() { int n; cout &lt;&lt; &quot;Enter...

Битовые операции (написать функцию для сброса в ноль двух битов с заданными номерами в коде символа) - C++
Вот наткнулся на интересную задачку: &quot;Написать функцию для сброса в ноль двух битов с заданными номерами в коде символа&quot; Во-первых...

Битовые операции, битовые поля. - C++
Здравствуйте! Еслть 4 диапазона чисел: 0-100, 0-100, 0-6000, 0-3. Сделать в виде битовых операций. Записать в unsigned int. Использовать...

Битовые операции и операции смещения языка С - C++
Доброго времени суток господа,помогите пожалуйста.Есть 2 кода к задаче,первый работает верно(переводит обычные числа в 16-ти ричные),а...

Битовые операции - C++
Имеется число int x = 85; // 1010101 - двоичное представление // 6543210 - номера битов // нужно взять // 0,2,3,4 биты и сложить...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Alex5
1052 / 715 / 105
Регистрация: 12.04.2010
Сообщений: 1,818
13.03.2014, 15:22 #2
Цитата Сообщение от танкист34 Посмотреть сообщение
получаются в основном одни FF
А что должно получаться? Что должен содержать массив itog[]?
1
танкист34
-62 / 0 / 0
Регистрация: 15.03.2013
Сообщений: 328
13.03.2014, 15:27  [ТС] #3
Alex5, я вас не совсем понял=)) не имеет значения какие биты в нём окажутся, так как это зависит от входного массива, думаю, это и так видно. Проблема в том, что почему то этот код не обратим.
Поясняю: если мы массив itog подадим на вход, то array мы не получим, хотя должен он получиться, но не получается. Может у меня глаз замылился и не вижу в чём ошибка.
Если нет у вас вариантов, то подскажите, пожалуйста, есть ли отладчик под Qt типа TD под DOS, чтобы каждый шаг отслеживать в HEX коде?

может вам будет интересно как я на вход подаю массив:
C++
1
2
3
4
for(int i = 0; i < "размер массива в байтах"; i++)
{
       sh(i);
}
PS: результат выходного массива ещё зависит от key
0
Alex5
1052 / 715 / 105
Регистрация: 12.04.2010
Сообщений: 1,818
13.03.2014, 15:55 #4
танкист34, я спрашиваю не о конкретных битах, а об правиле(алгоритме), как itog[] зависит от array[].
Чтобы найти ошибку в программе, надо знать исходную задачу.
1
танкист34
-62 / 0 / 0
Регистрация: 15.03.2013
Сообщений: 328
13.03.2014, 16:06  [ТС] #5
берём биты: первый, второй, четвёртый и пятый от key. Их ксорим XOR.
Полученное значение(бит) добавляем в переменную key, в старший разъряд. Так как key 12 разърядный, то я и выбрал значение 2048 длля установки 1 в 12 разъряд(по сути это 11 разряд, если от нуля считать).
А младший разъряд key перед потерей (всвязи со сдвигом), так как кол-во разърядов в key менять нельзя, XORим c младшим битом исходного массива и сохраняем в itog. Вот и всё.

Если кратко: то от key берутся указанные разряды, ксорятся, и результат в старший разъряд, а младший ксорится с младшим битом исходного массива и удаляется. И так до конца.

И получается, что это дело симметричное, я даже на бумаге раскладывал, а вот на машине не получается.
0
Alex5
1052 / 715 / 105
Регистрация: 12.04.2010
Сообщений: 1,818
13.03.2014, 17:24 #6
Цитата Сообщение от танкист34 Посмотреть сообщение
C++
1
2
3
4
int razr0 = razr_0 & key; //проверяем значения бит нужных разърядов
 int razr1 = razr_1 & key;
 int razr3 = razr_3 & key;
 int razr4 = razr_4 & key;
Пример. key == 31 ( в двоичной записи 11111 ). Тогда получим razr0 : 1, razr1 : 2, razr2 : 8, razr3 : 16.
Значения razr0, razr1, razr2, razr3 - либо 0, либо степени 2.
Цитата Сообщение от танкист34 Посмотреть сообщение
C++
1
2
int nov_bit = razr4 ^ razr3 ^ razr1 ^ razr0;
 if(nov_bit == 1)
Возможные значения nov_bit : 1, 2, 8, 16, 1+2, 1+8, 8+16 и т.п. Что Вы думаете об этом?
1
танкист34
-62 / 0 / 0
Регистрация: 15.03.2013
Сообщений: 328
13.03.2014, 17:50  [ТС] #7
а точно, я вообще капец запутался. Я предпологал, что единица вначале, хотя знал что она в нужном разъряде. Есть предположения исправить:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if(razr0 == 1) 
        kol_1 = kol_1 + 1;
        else kol_0 = kol_0 + 1;
        
        if(razr1 == 2)
            kol_1 = kol_1 + 1; 
        else kol_0 = kol_0 + 1;
        
        if(razr3 == 8)
            kol_1 = kol_1 + 1; 
        else kol_0 = kol_0 + 1;
        
        if(razr4 == 16)
            kol_1 = kol_1 + 1; 
        else kol_0 = kol_0 + 1;
Т.е. подсчитаем сколько всего единиц и нулей, а потом делаем вывод что получится. Если Нулей больше единиц или единиц больше нулей, то результат XOR будет 1, иначе 0. Но так тоже не робит
0
Alex5
1052 / 715 / 105
Регистрация: 12.04.2010
Сообщений: 1,818
13.03.2014, 18:11 #8
Какое начальное значение имеет itog[]? В приведённом коде есть операции вида itog[n] = itog[n] | 128; Но ведь результат зависит от исходного значения.
Цитата Сообщение от танкист34 Посмотреть сообщение
кол-во разърядов в key менять нельзя
Имеется в виду кол-во ненулевых битов?
Цитата Сообщение от танкист34 Посмотреть сообщение
C++
1
2
            //получаем новый бит == 0
            key = key >> 1; //удаляем младший бит
Может случиться, что младший бит равен 1, удаляется. А новый бит не добавляется.

Цитата Сообщение от танкист34 Посмотреть сообщение
есть ли отладчик под Qt типа TD
Если нет отладчика, можно добавить вывод на экран ( printf(), cout ) значений key, itog[] ( после каждого шага цикла, например ).
0
танкист34
-62 / 0 / 0
Регистрация: 15.03.2013
Сообщений: 328
13.03.2014, 18:20  [ТС] #9
Alex5, 1. все элементы массива itog по идее обнулены. следовательно или точно утсановит 1.
2. не только не нулевых, ведь число из 12 разърядов может и нули содержать. ex: 111000111000.
поэтому сдвиг на 1 и применяется, чтобы один добавить, а один удалить в итоге всегда 12 разърядов.
3. да, вот здесь и я думаю, не знаю до скольки надо счётчик цикла установить, либо до 7, либо до 8ми.
4. он есть, наверно, просто Qt для меня новинка. А cout это дедовский метод, но он только для консольных приложений, а я использую GUI.
Был бы отладчик, я бы уже давно сделал, там все кишки видно.
Спасибо, что помогаете.
0
Alex5
1052 / 715 / 105
Регистрация: 12.04.2010
Сообщений: 1,818
13.03.2014, 19:57 #10
Если сдвиг >> выполнять после добавления бита, то старший бит всегда будет нулевым. А информация о бите, установленном при i==0, будет потеряна.
Вот так, действительно, применяя вычисления к itog[], получаем исходный массив.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
 if(nov_kod_bit == 0)
{
    // ... 
}
else
{
    itog[n] = itog[n] >> 1;
    itog[n] = itog[n] | 128;
    
    // error 
    //itog[n] = itog[n] | 128;
    //itog[n] = itog[n] >> 1;
}
0
танкист34
-62 / 0 / 0
Регистрация: 15.03.2013
Сообщений: 328
14.03.2014, 03:14  [ТС] #11
Alex5, всё равно не обратимо получается
вот функция:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
void MainWindow::sh(int n)
{
 
int razr_0 = 1, razr_1 = 2, razr_3 = 8, razr_4 = 16; //для проверки значения тех разърядов которые подлжеат XOR
 
for(int i = 0; i < 8; i++) {
 
    int razr0 = razr_0 & key; //проверяем значения бит нужных разърядов
    int razr1 = razr_1 & key;
    int razr3 = razr_3 & key;
    int razr4 = razr_4 & key;
 
        int mlad_bit = razr_0 & array[n]; //младший бит элемента массива из файла
        array[n] = array[n] >> 1; //сдвигаем вправо, чтобы на следующем шаге опять проверять младший бит
 
                int kol_1 = 0; int kol_0 = 0;
 
                if(razr0 == 1) //здесь проверяем младший бит ключа
                kol_1 = kol_1 + 1;
                else kol_0 = kol_0 + 1;
 
                if(razr1 == 2)
                    kol_1 = kol_1 + 1;
                else kol_0 = kol_0 + 1;
 
                if(razr3 == 8)
                    kol_1 = kol_1 + 1;
                else kol_0 = kol_0 + 1;
 
                if(razr4 == 16)
                    kol_1 = kol_1 + 1;
                else kol_0 = kol_0 + 1;
 
                if(kol_1 > kol_0 || kol_0 > kol_1)
                {
                    //получаем новый бит == 1
                    key = key >> 1;
                    key = key | 2048;
                }
                else if (kol_1 == kol_0)
                {
                    //получаем новый бит == 0
                    key = key >> 1;
                    key = key | 0;
 
                }
 
        //********************************************************************************
        int nov_kod_bit = mlad_bit ^ razr0;
 
        if(nov_kod_bit == 0)
        {
            itog[n] = itog[n] >> 1;
            itog[n] = itog[n] | 0;
        }
        else
        {
            itog[n] = itog[n] >> 1;
            itog[n] = itog[n] | 128;
        }
 
    }
 
}
0
Alex5
1052 / 715 / 105
Регистрация: 12.04.2010
Сообщений: 1,818
14.03.2014, 14:29 #12
Цитата Сообщение от танкист34 Посмотреть сообщение
Alex5, всё равно не обратимо получается
Может быть, значение key не устанавливаете в исходное значение.
Где у Вас в коде, key = ...; for( i ... ) itog[i] = 0; ? (Кстати, key, array[] - где они объявлены? Это члены класса MainWindow?)
Цитата Сообщение от танкист34 Посмотреть сообщение
C++
1
void MainWindow::sh(int n)
Как Вы "подаёте на вход" itog[]? Ведь у функции MainWindow::sh() исходные данные берутся из array[], а результат записывается в itog[].
Может быть, стоит добавить array[], itog[], key в параметры функции?
0
танкист34
-62 / 0 / 0
Регистрация: 15.03.2013
Сообщений: 328
14.03.2014, 15:20  [ТС] #13
key точно устанавливается, так как я же данные полученные сохраняю в файл, а потом их обратно считываю(перезапуская программу). Щас я код в более приемлемый вид соберу и скину, а вообще меня смущает счётчик цикла я не пойму на 8 его ставить или на 7.
0
танкист34
-62 / 0 / 0
Регистрация: 15.03.2013
Сообщений: 328
16.03.2014, 16:45  [ТС] #14
Alex5, вот измененная функция, но проблема сохраняется, хотя сейчас проблема с увелечением первоначальных данных ушла, но исходные данные по этому алгоритму назад не получаются.
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
char MainWindow::sh(QByteArray array, int n) //на вход исходный массив и индекс байта
{
int razr_0 = 1, razr_1 = 2, razr_3 = 8, razr_4 = 16; //для проверки значения тех разърядов которые подлжеат XOR
char simv;
 
for(int i = 0; i < 8; i++) {
 
    int razr0 = razr_0 & key; //проверяем значения бит нужных разърядов
    int razr1 = razr_1 & key;
    int razr3 = razr_3 & key;
    int razr4 = razr_4 & key;
 
        int mlad_bit = razr_0 & array[n]; //младший бит элемента массива из файла
        array[n] = array[n] >> 1; //сдвигаем вправо, чтобы на следующем шаге опять проверять младший бит
 
                int kol_1 = 0; int kol_0 = 0;
 
                if(razr0 == 1) //здесь проверяем младший бит ключа
                kol_1 = kol_1 + 1;
                else kol_0 = kol_0 + 1;
 
                if(razr1 == 2)
                    kol_1 = kol_1 + 1;
                else kol_0 = kol_0 + 1;
 
                if(razr3 == 8)
                    kol_1 = kol_1 + 1;
                else kol_0 = kol_0 + 1;
 
                if(razr4 == 16)
                    kol_1 = kol_1 + 1;
                else kol_0 = kol_0 + 1;
 
                if(kol_1 > kol_0 || kol_0 > kol_1)
                {
                    //получаем новый бит == 1
                    key = key >> 1;
                    key = key | 2048;
                }
                else if (kol_1 == kol_0)
                {
                    //получаем новый бит == 0
                    key = key >> 1;
                    key = key | 0;
                }
        //********************************************************************************
        int nov_kod_bit = mlad_bit ^ razr0;
 
        if(nov_kod_bit == 0)
        {
            simv = simv >> 1;
            simv = simv | 0;
        }
        else
        {
            simv = simv >> 1;
            simv = simv | 128;
        }
 
    }
 
   return simv;
 
}
вызываю вот так:
C++ (Qt)
1
2
3
4
5
6
7
8
9
for(int n = 0; n < size_array; n++)
        {
            itog[n] = 0;  //предварительное обнуление
        }
 
        for(int n = 0; n < size_array; n++)
        {
           itog[n] = sh(array, n);
        }
Добавлено через 7 минут
переменную simv пробывал инициализировать нулём, результата также не последовало (в чём магия я не понимаю)
0
ValeryS
Модератор
6631 / 5038 / 466
Регистрация: 14.02.2011
Сообщений: 16,849
16.03.2014, 16:52 #15
Цитата Сообщение от танкист34 Посмотреть сообщение
берём биты: первый, второй, четвёртый и пятый от key. Их ксорим XOR.
Полученное значение(бит) добавляем в переменную key, в старший разъряд.
ну и как это как 4 бита превращаются в 1
это сложение вычитание И ИЛИ?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.03.2014, 16:52
Привет! Вот еще темы с ответами:

Битовые операции - C++
Собсно,если используется 4 байтовая переменная,то почему она представлена 16 битами(1010 0110 0010 0110),а не 32 битами?

Битовые операции - C++
Здравствуйте, необходимо разбить двухбайтное целое число на тетрады и поменять местами 2 и 3 тетрады, оставив без изменения 1 и 4. Есть...

Битовые операции - C++
Здраствуйте, помогите, пожалуйста! Надо написать три функции, используя только битовые (для первых двух) и только битовые и...

Битовые операции - C++
Задание: Как я понимаю надо создать объект типа int, но как менять местами биты вообще не представляю, помогите пожалуйста.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
16.03.2014, 16:52
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru