0 / 0 / 0
Регистрация: 19.06.2013
Сообщений: 14
1

Вычисление 8-и битных контрольной суммы

19.06.2013, 00:52. Показов 7018. Ответов 11
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток господа! Нужна ваша помощь. Есть функция на Си для вычисления 8-и битных контрольных сумм. Нужно транслировать её на C#. Или может кто нибудь знает как называется алгоритм, чтобы знать что гуглить, разобраться и закодить самому.


C
1
2
3
4
5
6
7
8
9
10
11
12
typedef unsigned char u1;
u1 cs(u1 const* buf, int count) {
enum {
bits = 8,
lShift = 2,
rShift = bits - lShift
};
#define ROT_LEFT(val) ((val « lSshift) | (val » rShift))
u1 res = 0;
while(count--) res = ROT_LEFT(res) ^ *buf++;
return ROT_LEFT(res);
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.06.2013, 00:52
Ответы с готовыми решениями:

Вычисление контрольной суммы файлов в отдельных потоках
Помогите,пожалуйста,искал в интернете,что то подобное,толком ничего не нашел. само задание:...

Вычисление контрольной суммы LRC
Здравствуйте! Пишу библиотеку для работы с одним устройством. В качестве эталона есть сторонняя...

Вычисление контрольной суммы
Всем Привет! У меня проблема с вычислением CRC16. Есть небольшое объяснение и примеры, но как...

Вычисление контрольной суммы
Всем доброго дня! Перенесите тему если не по адресу... Головоломлюсь с задачей. Пытаюсь...

11
Администратор
Эксперт .NET
9602 / 4744 / 761
Регистрация: 17.04.2012
Сообщений: 9,592
Записей в блоге: 14
21.06.2013, 16:38 2
Цитата Сообщение от vassisualii Посмотреть сообщение
может кто нибудь знает как называется алгоритм
CRC8
0
0 / 0 / 0
Регистрация: 19.06.2013
Сообщений: 14
21.06.2013, 17:35  [ТС] 3
Точно CRC8? я использовал этот метод, притом брал его именно из того источника на который вы прислали ссылку, но вычисленные мной контрольные суммы не совпали с прочитанными из файла. На мой взгляд я делал всё верно, поэтому предположил что алгоритм не тот.
0
Администратор
Эксперт .NET
9602 / 4744 / 761
Регистрация: 17.04.2012
Сообщений: 9,592
Записей в блоге: 14
21.06.2013, 17:46 4
@vassisualii, возможно метод предложенный вами вычисляет не CRC8, а другую контрольную сумму. Тогда переведём код на C# (внимание, не проверял код!):
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static char RotLeft(char val, int lShist, int rShift) {
    return (val << lShift) | (val >> rShift);
}
 
static char CS(char[] buffer, int count) {
    int bits = 8;
    int lShift = 2;
    int rShift = bits - lShift;
    char res = 0;
    int index = 0;
    
    while (count--)
        res = RotLeft(res, lShift, rShift) ^ buffer[index++];
    
    return RotLeft(res, lShift, rShift);
}
1
0 / 0 / 0
Регистрация: 19.06.2013
Сообщений: 14
21.06.2013, 17:55  [ТС] 5
Спосибо, могу ли я при использовании вашего кода заменить char на byte и char[] на byte[] ?
0
Администратор
Эксперт .NET
9602 / 4744 / 761
Регистрация: 17.04.2012
Сообщений: 9,592
Записей в блоге: 14
21.06.2013, 18:10 6
@vassisualii, да, можете. Я и сам должен был это сделать, ведь byte занимает 8 бит, а char - 16. И это имеет значение только с точки зрения читаемости кода - среда исполнения работает при вычислении с типом int, и переводит остальные целые в него. Так что выигрыша в производительности/потреблении памяти вы не получите.
0
0 / 0 / 0
Регистрация: 19.06.2013
Сообщений: 14
21.06.2013, 18:46  [ТС] 7
заменил char на byte получил следующий код:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  public class Checksum
    {
        static byte RotLeft(byte val, int lShift, int rShift)
        {
            return (val << lShift) | (val >> rShift);
        }
 
        static byte CS(byte[] buffer)
        {
            int bits = 8;
            int lShift = 2;
            int rShift = bits - lShift;
            byte res = 0;
            int index = 0;
            int count = buffer.Length;
 
            while (count--)
                res = RotLeft(res, lShift, rShift) ^ buffer[index++];
 
            return RotLeft(res, lShift, rShift);
        }
    }
при компиляции возникают 3 ошибки (похоже не канает преобразование типов):
В 5 и 18 строках: error CS0266: Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)
В 17 строке: error CS0029: Cannot implicitly convert type 'int' to 'bool'
Вы уж простите за назойливость, я в С# недавно)
0
Администратор
Эксперт .NET
9602 / 4744 / 761
Регистрация: 17.04.2012
Сообщений: 9,592
Записей в блоге: 14
21.06.2013, 18:55 8
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
public class Checksum
    {
        static byte RotLeft(byte val, byte lShift, byte rShift)
        {
            return (val << lShift) | (val >> rShift);
        }
 
        static byte CS(byte[] buffer)
        {
            byte bits = 8;
            byte lShift = 2;
            byte rShift = bits - lShift;
            byte res = 0;
            int index = 0;
            // иногда может понадобиться подсчитать контр. сумму не для всего буфера,
            // а только для определённого кол-ва бит. Для этого в исходном коде на С это вынесено в параметры
            int count = buffer.Length;
 
            while (count-- > 0)
                res = RotLeft(res, lShift, rShift) ^ buffer[index++];
 
            return RotLeft(res, lShift, rShift);
        }
    }
1
0 / 0 / 0
Регистрация: 19.06.2013
Сообщений: 14
21.06.2013, 19:17  [ТС] 9
в строках 5,12,20 остались ошибки:
error CS0266: Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)

Добавлено через 9 минут
проблему в пятой сроке решил так:

C#
1
            byte rShift = (byte)(bits - lShift);
как решить проблему с оператором сдвига И опер. "^" - пока не знаю.
и должен ли я в вместо
C#
1
2
            byte bits = 8;
            byte lShift = 2;
писать
C#
1
2
            byte bits = (byte)8;
            byte lShift = (byte)2;
?
0
Администратор
Эксперт .NET
9602 / 4744 / 761
Регистрация: 17.04.2012
Сообщений: 9,592
Записей в блоге: 14
21.06.2013, 20:01 10
Приношу извинения за наплевательское отношение к теме, теперь я всё проверяю в студии.
Повторюсь о малой пользе от использования byte, поэтому предложу вам такой код (проверил, работает)
Кликните здесь для просмотра всего текста
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
using System;
 
namespace ConsoleAppTest
{
    class Program
    {
        static int RotLeft(int val, int lShift, int rShift) {
            return (val << lShift) | (val >> rShift);
        }
 
        static int CS(int[] buffer) {
            int bits = 8;
            int lShift = 2;
            int rShift = bits - lShift;
            int res = 0;
            int index = 0;
            int count = buffer.Length;
 
            while (count-- > 0)
                res = RotLeft(res, lShift, rShift) ^ buffer[index++];
 
            return RotLeft(res, lShift, rShift);
        }
 
        static void Main() {
            int[] b = { 1, 2, 3, 4, 5, 6, 7, 8 };
            Console.WriteLine(CS(b));
        }
    }
}

Если вы настаиваете в необходимости повсеместного использования byte, то предложу менее красивый код
Кликните здесь для просмотра всего текста
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
using System;
 
namespace ConsoleAppTest
{
    class Program
    {
        static byte RotLeft(byte val, byte lShift, byte rShift) {
            return (byte)((val << lShift) | (val >> rShift));
        }
 
        static byte CS(byte[] buffer) {
            byte bits = 8;
            byte lShift = 2;
            byte rShift = (byte)(bits - lShift);
            byte res = 0;
            byte index = 0;
            int count = buffer.Length;
 
            while (count-- > 0)
                res = (byte)(RotLeft(res, lShift, rShift) ^ buffer[index++]);
 
            return RotLeft(res, lShift, rShift);
        }
 
        static void Main() {
            byte[] b = { 1, 2, 3, 4, 5, 6, 7, 8 };
            Console.WriteLine(CS(b));
        }
    }
}
1
0 / 0 / 0
Регистрация: 19.06.2013
Сообщений: 14
21.06.2013, 21:46  [ТС] 11
Всё работает, чексуммы вычисляются правильно, файлы парсятся. Большое спасибо!
ЗЫ
не совсем понял на счет использования массива int. т.к. я читаю и разбираю бинарные файлы и мне кажется более логичным использовать byte[].
0
Администратор
Эксперт .NET
9602 / 4744 / 761
Регистрация: 17.04.2012
Сообщений: 9,592
Записей в блоге: 14
21.06.2013, 21:51 12
Цитата Сообщение от vassisualii Посмотреть сообщение
мне кажется более логичным использовать byte[]
Ваше право.
0
21.06.2013, 21:51
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.06.2013, 21:51
Помогаю со студенческими работами здесь

Вычисление контрольной суммы
Обрабатываю в программе файл по работе. Наткнулся на необходимость изменение данных в этом файле....

Вычисление контрольной суммы
procedure TForm1.Button5Click(Sender: TObject); Var fSave:file of byte; j,k,Ks:Integer; begin...

Вычисление контрольной суммы CRC32
Столкнулся с проблемой... Есть процедурка вычисления crc32. Модули использовать не хочу, есть...

Вычисление контрольной суммы CRC16 (Modbus)
Нужна функция для вычисления CRC16 (Modbus). На входе есть данные (HEX) 01 17 80 01 11 02 DF 03...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru