перевести с С на паскаль
От: ironwit Украина  
Дата: 04.10.04 13:37
Оценка:
unsigned short crc (char *buf,unsigned char len)
{
    unsigned char   i, j;
    union {
        unsigned char   _crc[2];
        unsigned short  crc;
        } s;
    unsigned char   a, C, a1, C1;

        s.crc = 0;
        for (i=0; i<len; i++) {
          a =  (unsigned char)buf[i];
          a1 = (unsigned char)~buf[i];
          for (j=0; j<8; j++) {
            C = (unsigned char)(((s._crc[0] ^ a) & 0x01) << 7);
            C1 = (unsigned char)(((s._crc[1] ^ a1) & 0x01) << 7);
            if (C) s._crc[0] ^= 0x18;
            if (C1) s._crc[1] ^= 0x18;
            s._crc[0] = (unsigned char)((s._crc[0] >> 1) | C);
            s._crc[1] = (unsigned char)((s._crc[1] >> 1) | C1);
            a >>= 1;
            a1 >>= 1;
          }
        }
        return s.crc;
}


И если можно обьясните зачем создается массив, хотя из функции возвращается только число?
Заранее спасибо.
... << RSDN@Home 1.1.4 beta 3 0
Я не умею быть злым, и не хочу быть добрым.
Re: перевести с С на паскаль
От: jazzer Россия Skype: enerjazzer
Дата: 04.10.04 13:52
Оценка:
Здравствуйте, ironwit, Вы писали:

I>
I>unsigned short crc (char *buf,unsigned char len)
I>{
I>    unsigned char   i, j;
I>    union {
I>        unsigned char   _crc[2];
I>        unsigned short  crc;
I>        } s;
I>    unsigned char   a, C, a1, C1;

I>        s.crc = 0;
I>        for (i=0; i<len; i++) {
I>          a =  (unsigned char)buf[i];
I>          a1 = (unsigned char)~buf[i];
I>          for (j=0; j<8; j++) {
I>            C = (unsigned char)(((s._crc[0] ^ a) & 0x01) << 7);
I>            C1 = (unsigned char)(((s._crc[1] ^ a1) & 0x01) << 7);
I>            if (C) s._crc[0] ^= 0x18;
I>            if (C1) s._crc[1] ^= 0x18;
I>            s._crc[0] = (unsigned char)((s._crc[0] >> 1) | C);
I>            s._crc[1] = (unsigned char)((s._crc[1] >> 1) | C1);
I>            a >>= 1;
I>            a1 >>= 1;
I>          }
I>        }
I>        return s.crc;
I>}
I>


I>И если можно обьясните зачем создается массив, хотя из функции возвращается только число?

Ключевое слово — union.
В данном случае запись идет в массив _crc, а чтение — из short crc.
Предполагается, что они оба расположены по тому же адресу и short весит 2 байта.
Если этот код рассматривать как код С++ — он содержит в себе неопределенное поведение, так как нельзя записывать в один член объединения, а читать из другого.
Правильным было бы вообще не использовать объединение и его член crc, а использовать только массив _crc2, а потом указатель на его начало приводить к указателю на short:
return *(short*)_crc2;
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: перевести с С на паскаль
От: lst Россия  
Дата: 05.10.04 04:18
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Если этот код рассматривать как код С++ — он содержит в себе неопределенное поведение, так как нельзя записывать в один член объединения, а читать из другого.


А где в стандарте об этом можно прочитать? Я что-то не нашёл
Re[2]: перевести с С на паскаль
От: ironwit Украина  
Дата: 05.10.04 07:36
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Ключевое слово — union.

J>В данном случае запись идет в массив _crc, а чтение — из short crc.
J>Предполагается, что они оба расположены по тому же адресу и short весит 2 байта.
J>Если этот код рассматривать как код С++ — он содержит в себе неопределенное поведение, так как нельзя записывать в один член объединения, а читать из другого.

А Вы не могли бы описать что оно делает? Чтобы я мог его реализовать в паскале?
... << RSDN@Home 1.1.4 beta 3 0
Я не умею быть злым, и не хочу быть добрым.
Re[3]: перевести с С на паскаль
От: Auster Ниоткуда  
Дата: 13.10.04 10:21
Оценка:
Здравствуйте, ironwit, Вы писали:

I>А Вы не могли бы описать что оно делает? Чтобы я мог его реализовать в паскале?


Дык, судя даже по названию, эта функция подсчитывает CRC для блока данных из buf; CRC (контрольная суммя) используется обычно для контроля целостности данных. Причем этот алгоритм не похож на стандартный CRC16 и, ИМХО, далеко не самый эффективный.
Возможно стоит поискать другой сразу на паскале или делфях. Другое дело, если тебе прийдется работать со старыми файлами данных, в которых CRC посчитан именно этой функцией...

см. также http://www.rsdn.ru/article/files/classes/selfcheck.xml
Автор(ы): Алексей Кирюшкин
Дата: 07.09.2003
Реализация метода контроля целостности исполняемых файлов с использованием CRC
... << RSDN@Home 1.1.3 stable >>
Re[4]: перевести с С на паскаль
От: ironwit Украина  
Дата: 15.10.04 05:13
Оценка:
Здравствуйте, Auster, Вы писали:

A>Здравствуйте, ironwit, Вы писали:


I>>А Вы не могли бы описать что оно делает? Чтобы я мог его реализовать в паскале?

A>Возможно стоит поискать другой сразу на паскале или делфях. Другое дело, если тебе прийдется работать со старыми файлами данных, в которых CRC посчитан именно этой функцией...

Да в том то и дело, что необходимо использовать старый протокол в новых целях. Но оборудование никто изменять не будет, вот и приходится использовать то, что есть....
... << RSDN@Home 1.1.4 beta 3 0
Я не умею быть злым, и не хочу быть добрым.
Re: перевести с С на паскаль
От: Кодт Россия  
Дата: 15.10.04 10:06
Оценка: 3 (1)
Здравствуйте, ironwit, Вы писали:

I>И если можно обьясните зачем создается массив, хотя из функции возвращается только число?


Просто грязный код, вот и всё. У кого-то голова перегрелась в момент написания.

Переписываем на Паскаль буквально:
//unsigned short crc (char *buf,unsigned char len)
function crc(buf:PByte, len:ULong): Word; // нечего ограничивать длину буфера 255
//{
//    unsigned char   i, j;
//    union {
//        unsigned char   _crc[2];
//        unsigned short  crc;
//        } s;
//    unsigned char   a, C, a1, C1;
var
  ULong i;
  Byte j;
  Word crc0,crc1;
  Byte a0,a1,c0,c1;
begin
//        s.crc = 0;
  crc0:=0; crc1:=0;
//        for (i=0; i<len; i++) {
  for i:=0 to len-1 do begin
//          a =  (unsigned char)buf[i];
//          a1 = (unsigned char)~buf[i];
    a0:= buf[i]; a1 := not a0;
//          for (j=0; j<8; j++) {
    for j:=0 to 7 do begin
//            C = (unsigned char)(((s._crc[0] ^ a) & 0x01) << 7);
//            C1 = (unsigned char)(((s._crc[1] ^ a1) & 0x01) << 7);
      c0 := ((crc0 xor a0) and 1) shl 7;
      c1 := ((crc1 xor a1) and 1) shl 7;
//            if (C) s._crc[0] ^= 0x18;
//            if (C1) s._crc[1] ^= 0x18;
      if(c0<>0) crc0 := crc0 xor $18;
      if(c1<>0) crc1 := crc1 xor $18;
//            s._crc[0] = (unsigned char)((s._crc[0] >> 1) | C);
//            s._crc[1] = (unsigned char)((s._crc[1] >> 1) | C1);
      crc0:=(crc0 shr 1) or c0;
      crc1:=(crc1 shr 1) or c1;
//            a >>= 1;
//            a1 >>= 1;
      a0:=a0 shr 1;
      a1:=a1 shr 1;
//          }
    end;//for j
//        }
  end;//for i
//        return s.crc;
  crc := Word(crc0) or (Word(crc1) shr 8); // little endian order
//}
end;
Перекуём баги на фичи!
Re[2]: перевести с С на паскаль
От: Кодт Россия  
Дата: 15.10.04 10:07
Оценка:
Багфикс маленький
К>  crc := Word(crc0) or (Word(crc1) shl 8); // little endian order
Перекуём баги на фичи!
Re[2]: перевести с С на паскаль
От: ironwit Украина  
Дата: 15.10.04 10:14
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, ironwit, Вы писали:


I>>И если можно обьясните зачем создается массив, хотя из функции возвращается только число?


К>Просто грязный код, вот и всё. У кого-то голова перегрелась в момент написания.


К>Переписываем на Паскаль буквально:

Спасибо, вот это я хоть прочитать могу
... << RSDN@Home 1.1.4 beta 3 0
Я не умею быть злым, и не хочу быть добрым.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.