Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > контрольная сумма для ИРТ1730D/M


Автор: debil 28.1.2008, 19:32
В описании на железо ( ИРТ1730D/M ) указано как подсчитывать контрольную сумму и приведен пример на паскале. Помогите перевести на С  smile .                
Сколько раз сталкивался с разным железом, даже у одного производителя на каждое железо разный алгоритм подсчета контрольных сумм, никакой унификации….                                            
Способ подсчета контрольной суммы для ИРТ1730
Для подсчета контрольной суммы необходимо выполнить следующие шаги:
1.    Загружаем 16-битную беззнаковую (word) переменную (KS) всеми единицами (KS=65535).
2.    Выполняем операцию "ИСКЛЮЧАЮЩЕЕ ИЛИ" над первым байтом массива, который защищается контрольной суммой, и младшим байтом переменной KS. Результат заносится в переменную KS.
3.    Сдвигаем KS на 1 бит вправо, при этом самый левый бит делаем равным нулю.
4.    Условные действия
4.1.    Если выдвинутый бит равен 1, выполняется операция "ИСКЛЮЧАЮЩЕЕ ИЛИ" над переменной KS и числом 40961(десятичное). Результат заносится в переменную KS.
4.2.    Если выдвинутый бит равен 0, выполняем переход на пункт 3.
5.    Повторить пункты 3 и 4 пока не будет выполнено 8 сдвигов.
6.    Повторить пункты 2,3,4 и 5 со следующим байтом массива, защищаемого контрольной суммой.
7.    Содержимое полученной переменной KS и есть контрольная сумма.

Пример подсчета контрольной суммы на языке паскаль

Код



Program K_S;
Var
  ST: String;

function KSUM(var S: String): String;
var
  i, l: Integer;
  KS: Word;
  SS: String;
begin
  KS := 65535;
  for i:=2 to Length(S) do
  begin
    KS := KS xor Ord(S[i]);
    for l:=1 to 8 do
     if (KS div 2)*2<>KS then KS := (KS div 2) xor 40961
     else KS := (KS div 2);
  end;
  Str(KS, SS); { Преобразование KS в текстовый вид }
  KSUM := SS;
end;




Автор: xvr 29.1.2008, 10:15
Цитата(debil @ 28.1.2008,  19:32)
В описании на железо ( ИРТ1730D/M ) указано как подсчитывать контрольную сумму и приведен пример на паскале. Помогите перевести на С  smile .                
Сколько раз сталкивался с разным железом, даже у одного производителя на каждое железо разный алгоритм подсчета контрольных сумм, никакой унификации….                                            
Способ подсчета контрольной суммы для ИРТ1730
Для подсчета контрольной суммы необходимо выполнить следующие шаги:
1.    Загружаем 16-битную беззнаковую (word) переменную (KS) всеми единицами (KS=65535).
2.    Выполняем операцию "ИСКЛЮЧАЮЩЕЕ ИЛИ" над первым байтом массива, который защищается контрольной суммой, и младшим байтом переменной KS. Результат заносится в переменную KS.
3.    Сдвигаем KS на 1 бит вправо, при этом самый левый бит делаем равным нулю.
4.    Условные действия
4.1.    Если выдвинутый бит равен 1, выполняется операция "ИСКЛЮЧАЮЩЕЕ ИЛИ" над переменной KS и числом 40961(десятичное). Результат заносится в переменную KS.
4.2.    Если выдвинутый бит равен 0, выполняем переход на пункт 3.
5.    Повторить пункты 3 и 4 пока не будет выполнено 8 сдвигов.
6.    Повторить пункты 2,3,4 и 5 со следующим байтом массива, защищаемого контрольной суммой.
7.    Содержимое полученной переменной KS и есть контрольная сумма.

Пример подсчета контрольной суммы на языке паскаль

Код



Program K_S;
Var
  ST: String;

function KSUM(var S: String): String;
var
  i, l: Integer;
  KS: Word;
  SS: String;
begin
  KS := 65535;
  for i:=2 to Length(S) do
  begin
    KS := KS xor Ord(S[i]);
    for l:=1 to 8 do
     if (KS div 2)*2<>KS then KS := (KS div 2) xor 40961
     else KS := (KS div 2);
  end;
  Str(KS, SS); { Преобразование KS в текстовый вид }
  KSUM := SS;
end;




Буйный алгоритм  smile 
Уточнение - а точно подсчет начинается со 2го символа строки? Или это опечатка/баг?
Еще вопрос - входая строка текстовая, или туда упакованны бинарные данные? (Предполагаю, что текстовая)
Код

int KSUM(char* S) // returns summ as number, not as string as in original prog!
{
 int l;
 unsigned short KS=-1;
  for(++S;*S;++S)
   {
    KS ^= *(unsigned char*)S;
    for(l=0;l<8;++l)
     if (KS&1) KS = (KS>>1) ^ 40961;
     else KS >>= 1;
   }
 return KS;
}

Автор: debil 29.1.2008, 18:11
Код

unsigned short GetSum( short *Data, int Size)
{
  unsigned short cs = 65535;
  for(int i = 1; i < Size; i++) // первый байт-двоеточие в подсчете не участвует 
                                             // ( описание на прибор)
    {
     cs ^= Data[i];
     for(int l = 8; l; l--)
       {
        if(cs&1) cs = (cs>>1) ^ 40961;
           else  cs = cs>>1;
       }
    }
    return cs;
}



Спасибо всем smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)