Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
0 / 0 / 0
Регистрация: 29.01.2015
Сообщений: 4

Манипуляции с битами

29.01.2015, 20:23. Показов 2867. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В одном из проектов парсятся бинарные данные, среди которых встречается структура вида [длина][данные]. Так вот длина данных может быть записана в 1 - 4 байтах. Чтобы получить [длину], выполняются следующие действия:
1. смотрим первый байт, если старший бит = 0, то [длина] занимает 1 байт. Данный байт приводится к типу UInt32.
2. если старший бит первого байта = 1 , значит [длина] занимает > 1 байта. Смотрим следующий байт, также проверяем значение старшего бита. Если оно опять = 1, то переходим к следующему и т.д. Последним байтом будет байт, в котором значение старшего бита = 0.

Допустим количество байтов, которое занимает [длина], определено и = 2 - для примера [ 81 0d ].
Чтобы получить необходимое значение [длины], необходимо убрать старшие биты в байтах, являющиеся по сути флагами.
Т.е. для 81 битовая последовательность - 10000001, для 0d - 00001101. Убираем старшие биты: 0000001 и 0001101. Склеиваем: 10001101 - вот это и есть итоговое нужное значение [длина]. Остается теперь его только привести к UInt32.

Собственно как реализовать манипуляции с битами и последующее приведение к единому типу UInt32.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.01.2015, 20:23
Ответы с готовыми решениями:

Манипуляции с БД
Пишу программу, для работы которой необходима БД. Но проблема заключается в том, что я не могу могу подключить базу данных и,...

Манипуляции с массивом
дано такое задание: 1.вычислить количество элементов массива,которые ровны нулю 2.сумму элементов массива,размещенных после...

Манипуляции с DataGridView
Всем дд! Как сделать чтобы при нажатии на строку в DataGridView правой кнопкой мыши, выпадало меню с набором функции "добавить",...

10
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
29.01.2015, 22:40
BitArray
BinaryConverter
BinaryReader
0
0 / 0 / 0
Регистрация: 29.01.2015
Сообщений: 4
29.01.2015, 23:18  [ТС]
Про данные вещи мне известно. Собственно не понятно как перейти к работе с самими битами.
т.е. к примеру как от массива типа byte[] с теми же элементами [ 81 0d ] начать работать с битовой последовательность вида [1000000100001101]. Вот как, скажем так, правильней было бы реализовать этот нюанс?
Т.к. в том же BitArray я конструктора, приводящего значения из byte[] или хотя бы из int в битовую последовательность я не нашел.
0
 Аватар для mbean
46 / 42 / 14
Регистрация: 18.02.2012
Сообщений: 82
30.01.2015, 00:55
Побитовые операторы
0
0 / 0 / 0
Регистрация: 29.01.2015
Сообщений: 4
30.01.2015, 01:04  [ТС]
Приведите простой пример как побитовыми операторами вырезать 1й и 9й биты из UInt16 [1000000100001101], чтобы стало [0000000010001101].
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
30.01.2015, 01:28
Цитата Сообщение от kuzmich Посмотреть сообщение
конструктора, приводящего значения из byte[] или хотя бы из int в битовую последовательность я не нашел.
Ну если нет подходящего конструктора - сделаем свое, что тут делать-то ? Это ж пять минут работы:

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication156
{
    class Program
    {
        static void Main(string[] args)
        {
            var data = new byte[] {0x81, 0x0d};
            var br = new BitReader(data);
            br.Seek(1);//skip first bit
            var n1 = br.Read(7);//read 7 bits
            br.Seek(1);//skip first bit
            var n2 = br.Read(7);//read 7 bits
 
            var result = (n1 << 7 | n2);
        }
    }
 
    /// <summary>
    /// Reads byte array as stream of bits
    /// </summary>
    class BitReader
    {
        public int Position = 0;
        private byte[] source;
 
        public BitReader(byte[] source)
        {
            this.source = source;
        }
 
        public int Length { get { return source.Length*8; } }
 
        /// <summary>
        /// Reads bitCount bits from stream and return as UInt32
        /// </summary>
        public UInt32 Read(int bitCount)
        {
            UInt32 res = 0;
 
            for (int i = 0; i < bitCount; i++)
            {
                var bit = Read();
                if (bit < 0)
                    throw new Exception("Can not read needed count of the bits");
                unchecked
                {
                    res = (res << 1) | (UInt32) bit;
                }
            }
 
            return res;
        }
 
        /// <summary>
        /// Reads one bit from stream
        /// </summary>
        public int Read()
        {
            if (Position >= Length) return -1;
            var i = Position / 8;
            var j = Position % 8;
            Position++;
            return (source[i] >> (7 - j)) & 0x01;
        }
 
        /// <summary>
        /// Moves Position
        /// </summary>
        public bool Seek(int shift)
        {
            Position += shift;
            if (Position < 0)
            {
                Position = 0;
                return false;
            }
 
            if (Position >= Length)
            {
                Position = Length - 1;
                return false;
            }
 
            return true;
        }
    }
}
1
 Аватар для mbean
46 / 42 / 14
Регистрация: 18.02.2012
Сообщений: 82
30.01.2015, 01:29
Так вырезаем:
C#
1
2
value = value ^ (1<<15);
value = value ^ (1<<7);
Так проверяем наличие бита:
C#
1
bool exist = (value & (1<<15)) != 0
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18302 / 14226 / 5368
Регистрация: 17.03.2014
Сообщений: 28,900
Записей в блоге: 1
30.01.2015, 11:00
kuzmich, я бы сделал так:
C#
1
2
3
4
5
6
7
byte[] data = ....;
int length = data[0] > 0x7F ? (byte)(data[0] ^ 0x80) : data[0];
for (int i=0; data[i] > 0x7F; i++)
{
    byte nextByte = data[i+1] > 0x7F ? (byte)(data[i+1] ^ 0x80) : data[i+1];
    length = (length << 7) | nextByte;
}
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
30.01.2015, 15:17
OwenGlendower, у вас будет выход за границы массива, если значение длины будет 0xFFFFFFF.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        static int GetLength(byte[] buff, int offset = 0)
        {
            int length = 0;
            int count = Math.Min(buff.Length - offset, 4);
 
            int i = 0;
 
            while (true)
            {
                length |= buff[i + offset] & 0x7F;
 
                if ((buff[i + offset] & 0x80) == 0 || ++i == count)
                    return length;
 
                length <<= 7;
            }
        }
SetLength
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        static int SetLength(byte[] buff, int offset, int length)
        {
            if (length > 0xFFFFFFF)
                throw new Exception("Invalid value.");
 
            length &= 0xFFFFFFF;
 
            int bytesWrited = 0;
            int shift = 21;
 
            do
            {
                var value = length >> shift;
                if (value != 0)
                    buff[offset + bytesWrited++] = (byte)(value | (shift != 0 ? 128 : 0));
            }
            while (((shift -= 7) & 0x80000000) == 0);
 
            return offset + bytesWrited;
        }
1
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18302 / 14226 / 5368
Регистрация: 17.03.2014
Сообщений: 28,900
Записей в блоге: 1
30.01.2015, 20:33
Цитата Сообщение от NickoTin Посмотреть сообщение
у вас будет выход за границы массива, если значение длины будет 0xFFFFFFF
Согласен. Кроме того следует проверять что кол-во байтов с длиной не больше 4. Я исходил из того что ТС самостоятельно это реализует. Кроме того возможно он уже валидирует даннные и описанных ситуаций не может возникнуть. На всякий случай исправленный вариант:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int GetLength(byte[] buf, int offset)
{
    if (buf == null) throw new ArgumentNullException("buf");
    if (offset < 0) throw new ArgumentOutOfRangeException("offset", "Offset must be positive number or zero");
    if (offset >= buf.Length) throw new ArgumentOutOfRangeException("offset", "Offset must be within the bounds of the buffer");
 
    int length = buf[offset] & 0x7F;
    for (int idx=offset+1, count=0; buf[idx-1] > 0x7F; count++, idx++)
    {
        if (idx>=buf.Length || count>3 || (count==3 && buf[idx]>0x7F)) throw new InvalidOperationException();
        
        byte nextByte = (byte)(buf[idx] & 0x7F);
        length = (length << 7) | nextByte;
    }
    return length;
}
1
0 / 0 / 0
Регистрация: 29.01.2015
Сообщений: 4
31.01.2015, 18:44  [ТС]
Всем спасибо за помощь, разобрался.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
31.01.2015, 18:44
Помогаю со студенческими работами здесь

Манипуляции с массивом
Нужна помощь, суть такая я читаю левый xml файл на другом сервере, вот так: $xml = simplexml_load_file(ssil); В этом .xml файле...

Манипуляции с картинкой
Всем привет. На сайт магазина нужно вставить картинки товара. Но...=) Картинка на против товара должна быть 50х50(примерно) Но при...

Манипуляции с формой
Всем доброго времени суток..............скажите пожалуйста уважаемые мастера как сделать так, что бы 2 форма при перемещении ее курсором,...

Манипуляции с курсором
Например я создал экземпляр класса, в нём есть картинка, она выведена на форму. Как мне проводить манипуляции с кодом если я нажал на эту...

Манипуляции с формами
Здравствуйте. Господа, поведайте пожалуйста, что можно делать с формами? Можно ли их сохранять, подгружать к проектам, можно ли формы C#...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru