Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.11.2021, 20:36   #51
sergey.serg-72
Форумчанин
 
Регистрация: 12.03.2019
Сообщений: 376
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
function reverse(f: Word): Word;
begin
f := ((f shr 1) and $5555) or ((f and $5555) shl 1);
f := ((f shr 2) and $3333) or ((f and $3333) shl 2);
f := ((f shr 4) and $0F0F) or ((f and $0F0F) shl 4);
f := (f shr 8) or (f shl 8);

\
Result := f;
end;
Если я правильно понял эта функция универсальная для всех типов CRC 16 , которая позволяет делать лож и истина , функция реверсирования reverse ?

Цитата:
Сообщение от BDA Посмотреть сообщение
Не всё так просто. CCITT от CDMA2000 отличался только параметрами Init и Poly (которые вы меняете в двух строках кода). Но ARC отличается от CCITT еще и параметрами RefIn и RefOut, которые тоже нужно как-то учесть при подсчете. Чтобы самому проверить правильность реализации алгоритма, просто считайте контрольную сумму строки "123456789" и сравнивайте со столбцом Check в таблице на Википедии.
Сейчас прочитаю статью, я вчера две прочитал тоже нашёл, но все без примеров.

BDA, это же гениально что Вы сделали при помощи такой конструкции, можно создавать любой, на выбор из таблицы алгоритм.
Прочитал статью, именно об этом и шла речь, статья прекрасная .

Вот из Вашего урока, взял создал 2 функции , если не трудно проверьте, правильно сделал я ?

Код:
function CRC16MODBUS(P: PChar; Len: Word): Word;
begin
  Result := CRC16(P, Len, $8005, $FFFF, 0, True, True);
end;
Код:
 function CRC16AUGCCITT(P: PChar; Len: Word): Word;
begin
  Result := CRC16(P, Len, $1021, $1D0F, 0, False, False);
end;
Удручает только одно : мы потеряли часть важного кода, а именно ;

Код:
function CRC16XMODEM(P: PChar; Len: Word; skip_i: Integer): Word;
skip_i без этой процедуры плохо, так как ,нет теперь возможности вводить через едит , байт пропуска
И важную часть кода потеряли :
Код:
for i := 0 to Len - 1 do
begin
if i = skip_i then
continue;
Код:
 crc :=CRC16CCITT(PChar(buffer), buf_len, skip_ - addr1);
А чтоб сделать как на старой версии вводить байт пропуска, надо ещё функцию отдельно, или дополнить можно новую ?.

А то программа уже с едит и есть тестовый файл.
Чтоб с едит как то сделать и вообще супер !
Это реально, или всё переделывать надо?

Пробую функцию, так :
Код:
function CRC16CDMA2000(P:PChar; Len: Word; skip_i: Word): Word;
var
i, j: Integer;
begin
Result :=$FFFF;
for i := 0 to Len - 1 do
if i = skip_ then
continue;
Result := CRC16(P, Len, $C867, $FFFF, 0, False, False);
end;

Код:
crc :=CRC16CDMA2000(PChar(buffer), buf_len, skip_i - addr1);
Без едит результат : C3D9, с новой функцией F3BA

Явно не совпадение, где то я ошибся

Последний раз редактировалось BDA; 16.11.2021 в 03:28.
sergey.serg-72 вне форума Ответить с цитированием
Старый 16.11.2021, 03:27   #52
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,318
По умолчанию

Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
Если я правильно понял эта функция универсальная для всех типов CRC 16 , которая позволяет делать лож и истина , функция реверсирования reverse ?
Что-то не очень понял вопрос. Функция CRC16 универсальная (можно получить любой CRC-16 алгоритм, опираясь на таблицу по методике Ross N. Williams). А функция reverse просто вспомогательная, которая меняет порядок битов в числе размера Word на обратный.
Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
можно создавать любой, на выбор из таблицы алгоритм.
Да, но "крутить" каждый байт очень некрасиво.
Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
function CRC16MODBUS(P: PChar; Len: Word): Word;
function CRC16AUGCCITT(P: PChar; Len: Word): Word;
Да, вроде константы совпадают с таблицей.
Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
Пробую функцию, так
Вам нужно совместить старую версию функции CRC16CCITT и новую универсальную функцию CRC16. А именно, добавить в нее параметр skip_i и if с условием пропуска, а в промежуточные функции с константами добавить только параметр skip_i.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 16.11.2021, 04:04   #53
sergey.serg-72
Форумчанин
 
Регистрация: 12.03.2019
Сообщений: 376
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Вам нужно совместить старую версию функции CRC16CCITT и новую универсальную функцию CRC16. А именно, добавить в нее параметр skip_i и if с условием пропуска, а в промежуточные функции с константами добавить только параметр skip_i.

Делаю так добавляю в универсальную функцию :
Код:
 function CRC16(P: PChar; Len, skip_i, Poly, Init, XorOut: Word; RefIn, RefOut: Boolean): Word;
var
  i, j: Integer;
begin
  Result := Init;
  for i := 0 to Len - 1 do
  if i = skip_i then
continue;

 begin

if RefIn then
      Result := Result xor reverse(ord(P[i]))
    else
      Result := Result xor (ord(P[i]) shl 8);
    for j := 0 to 7 do
    begin
      if (Result and $8000) <> 0 then
        Result := (Result shl 1) xor Poly
      else
        Result := Result shl 1;
    end;
  end;
  if RefOut then
    Result := reverse(Result);
  Result := Result xor XorOut;
end;
Всё вроде нормально встало.


А вот дальше с промежуточной проблема :

Код:
 function CRC16CCITT(P: PChar; Len, skip_i : Word): Word;
begin
  Result := CRC16(P, Len, $1021, $FFFF, 0, False, False);
end;
Компилятор в ошибку уходит пишет что word and bolean что то не совместимо. как я понял.
значит что то не так сделал.

Последний раз редактировалось sergey.serg-72; 16.11.2021 в 04:10.
sergey.serg-72 вне форума Ответить с цитированием
Старый 16.11.2021, 04:15   #54
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,318
По умолчанию

Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
добавляю в универсальную функцию
Только этот if уже после begin, а не до нужно вставить. И лучше не делать skip_i типа Word, так как нужно поддерживать отрицательные значения (если начальный адрес ввели больше, чем адрес игнорирования).
Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
А вот дальше с промежуточной проблема
Так вы никуда skip_i не пристроили в вызов CRC16.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 16.11.2021, 04:22   #55
sergey.serg-72
Форумчанин
 
Регистрация: 12.03.2019
Сообщений: 376
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Только этот if уже после begin, а не до нужно вставить. И лучше не делать skip_i типа Word, так как нужно поддерживать отрицательные значения (если начальный адрес ввели больше, чем адрес игнорирования).

Вот в универсальной исправил так ;
Код:
function CRC16(P: PChar; Len,skip_i : Integer;  Poly, Init, XorOut: Word; RefIn, RefOut: Boolean): Word;
var
  i, j: Integer;
begin
  Result := Init;

begin

  for i := 0 to Len - 1 do
  if i = skip_i then
continue;

if RefIn then
      Result := Result xor reverse(ord(P[i]))
    else
      Result := Result xor (ord(P[i]) shl 8);
    for j := 0 to 7 do
    begin
      if (Result and $8000) <> 0 then
        Result := (Result shl 1) xor Poly
      else
        Result := Result shl 1;
    end;
  end;
  if RefOut then
    Result := reverse(Result);
  Result := Result xor XorOut;
end;
Цитата:
Сообщение от BDA Посмотреть сообщение
Так вы никуда skip_i не пристроили в вызов CRC16.
Вот в этом моменте заблудился, не допонял .

Цитата:
Сообщение от BDA Посмотреть сообщение
Так вы никуда skip_i не пристроили в вызов CRC16.
кажется врубился и сделал так :
Код:
 function CRC16CCITT(P: PChar; Len: Word; skip_i: Integer): Word;
begin
  Result := CRC16(P, Len, skip_i ,  $1021, $FFFF, 0, False, False);
end;


А в универсальной функции подправил :

Код:
 function CRC16(P: PChar; Len: Word; skip_i: Integer ; Poly, Init, XorOut: Word; RefIn, RefOut: Boolean): Word;

Последний раз редактировалось BDA; 16.11.2021 в 04:34.
sergey.serg-72 вне форума Ответить с цитированием
Старый 16.11.2021, 04:33   #56
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,318
По умолчанию

Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
кажется врубился и сделал так
Да, теперь нормально.
Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
Вот в универсальной исправил так
Все-таки begin должен быть между for и if.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 16.11.2021, 04:51   #57
sergey.serg-72
Форумчанин
 
Регистрация: 12.03.2019
Сообщений: 376
По умолчанию

Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
function CRC16CCITT(P: PChar; Len: Word; skip_i: Integer): Word;
begin
Result := CRC16(P, Len, skip_i , $1021, $FFFF, 0, False, False);
end;
Нет неправильно в ошибку уходит. ни как не пойму я этот момент

Нет не получается вроде всё проставил, но нет в ошибку и всё тут, не пойму что не так и в универсальной функции не так получается и в промежуточной не так.

Цитата:
Сообщение от BDA Посмотреть сообщение
Вам нужно совместить старую версию функции CRC16CCITT и новую универсальную функцию CRC16. А именно, добавить в нее параметр skip_i и if с условием пропуска, а в промежуточные функции с константами добавить только параметр skip_i.
Не выходит , у меня совместить и добавить в промежуточные функции только параметр.

Последний раз редактировалось BDA; 19.11.2021 в 18:49.
sergey.serg-72 вне форума Ответить с цитированием
Старый 16.11.2021, 05:58   #58
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,318
По умолчанию

Так каков текущий код? Что пишет компилятор?
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 16.11.2021, 06:25   #59
sergey.serg-72
Форумчанин
 
Регистрация: 12.03.2019
Сообщений: 376
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Так каков текущий код? Что пишет компилятор?
текущей код универсальная функция :
Код:
function CRC16(P: PChar; Len: Word; 
 skip_i : Integer;  Poly, Init, XorOut: Word; RefIn, RefOut: Boolean): Word;
var
  i, j: Integer;
begin
  Result := Init;

begin

  for i := 0 to Len - 1 do
  if i = skip_i then
continue;

if RefIn then
      Result := Result xor reverse(ord(P[i]))
    else
      Result := Result xor (ord(P[i]) shl 8);
    for j := 0 to 7 do
    begin
      if (Result and $8000) <> 0 then
        Result := (Result shl 1) xor Poly
      else
        Result := Result shl 1;
    end;
  end;
  if RefOut then
    Result := reverse(Result);
  Result := Result xor XorOut;
end;


промежуточная функция :
Код:
 
 function CRC16CCITT(P: PChar; Len: Word; skip_i: Integer): Word;
begin
  Result := CRC16(P, Len, skip_i ,  $1021, $FFFF, 0, False, False);
end;

компилятор пишет ; incompahble types '' word and booiiean''
sergey.serg-72 вне форума Ответить с цитированием
Старый 16.11.2021, 06:39   #60
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,318
По умолчанию

Вы пока не исправили ошибку со "скачущим" begin (но это влияет на неверность расчета, но не на компилируемость). Скопировал ваш код как есть и не получил ошибок. Значит ошибка закралась в вызов функции CRC16CCITT.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Opendialog завис DimOn4Ik Общие вопросы Delphi 12 02.11.2018 16:08
Реализация суммы в простом варианте. Mariolka PHP 8 10.11.2016 15:50
С++ сортировка в текстовом файле. (Задание на курсовик никак не получается) Evg888 Помощь студентам 1 02.06.2012 19:37
Житейская задачка о простом копировании mephist Помощь студентам 11 16.05.2009 20:42