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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 11.11.2021, 19:52   #21
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
Adr2=$02D-$05E;
Не знаю, сработает ли сложение. В глаза бросается отрицательный Adr2.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Старый 11.11.2021, 19:55   #22
sergey.serg-72
Форумчанин
 
Регистрация: 12.03.2019
Сообщений: 376
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Можно пойти разными путями. Или "готовить" входные данные, исключая ненужный байт, или засунуть логику пропуска прямо в функцию подсчета (топорно, зато меньше думать):
BDA , а можно как то узнать контрольную сумму, как то подсчитать?
А то на что ориентироваться ? какая должна быть правильная сумма ?

Попробовал по вашему методу, выходит другая сумма, а как узнать правильную?
Онлайн калькулятор, думаю не поможет ?
Сделал по вашему так :
Код:
function CRC16CCITT(P: PChar; Len: Word): Word;
var
i, j: Integer;
begin
Result :=0;
for i := 0 to Len - 1 do

begin
 if i = $2C then
  continue;

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 $1021
else
Result := Result shl 1;
end;
end;
end;
А так, будет правильно подсчитано?

Цитата:
Сообщение от BDA Посмотреть сообщение
Не знаю, сработает ли сложение. В глаза бросается отрицательный Adr2.
Сложение срабатывает и выводит сумму, вопрос в другом, а правильная ли она ?
Надо знать точную , правильную сумму, тогда можно вывод сделать, а так , получается разными методами, на выходе разные суммы, какая из них правильная ?

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

Не знаю, зачем вы отказались от использования "TBytes = array of Byte;" в пользу string (как было в старой программе bin->hex).
Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
Сложение срабатывает
Когда я говорю "сработает", то имею ввиду, что программа корректна и выдает правильный результат.
Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
Сложение срабатывает и выводит сумму, вопрос в другом, а правильная ли она ?
Попробуйте все-таки в своем коде исправить adr2. Глядишь и совпадут суммы.
Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
а можно как то узнать контрольную сумму, как то подсчитать?
Конечно можно. Просто удалите в файле ненужный байт и считайте контрольную сумму этого файла чем хотите (хоть онлайн, хоть редакторами).
Еще можно избежать сложения буферов, чуть изменив функцию:
Код:
function CRC16XMODEM(P: PChar; Len, Init: Word): Word;
begin
    Result := Init;
    ...

crc := CRC16XMODEM(PChar(Buffer2), Adr2, CRC16XMODEM(PChar(Buffer1), Adr1, 0));
Код не запускал, так что это только в качестве наброска идеи.

Опять же, лучший подход сложно выбрать, не зная, куда выведет фантазия преподавателя по части выдумывания новых усложнений. Если он предложит еще парочку байтов выколоть, то устанешь кусочками читать.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 11.11.2021 в 20:20.
BDA на форуме Ответить с цитированием
Старый 11.11.2021, 20:36   #24
sergey.serg-72
Форумчанин
 
Регистрация: 12.03.2019
Сообщений: 376
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Конечно можно. Просто удалите в файле ненужный байт и считайте контрольную сумму этого файла чем хотите (хоть онлайн, хоть редакторами).
Еще можно избежать сложения буферов, чуть изменив функцию:
Удалил в редакторе , получилась сумма : 69АС, при этом произошло смещение на один байт, а смещение не влияет на сумму?

Цитата:
Сообщение от BDA Посмотреть сообщение
Попробуйте все-таки в своем коде исправить adr2. Глядишь и совпадут суммы.
Не совсем понял, а что в коде исправить adr2.?

Цитата:
Сообщение от BDA Посмотреть сообщение
Код не запускал, так что это только в качестве наброска идеи.

Опять же, лучший подход сложно выбрать, не зная, куда выведет фантазия преподавателя по части выдумывания новых усложнений. Если он предложит еще парочку байтов выколоть, то устанешь кусочками читать.
Ни один из вариантов, не ведёт к нужной сумме, лучше конечно функцией отделаться, проще и лучше, но
Код:
 function CRC16XMODEM(P: PChar; Len, Init: Word): Word;
var
i, j: Integer;
begin
  Result := Init;
for i := 0 to Len - 1 do
begin
if i = $02C then
continue;
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 $1021
else
Result := Result shl 1;
end;
end;
end;

Этот вариант не выводит правильную сумму, хотя вариант был бы оптимальным.
Нет, думаю, что больше не должен препод изголитса чтоб по байтно группу.

Цитата:
Сообщение от BDA Посмотреть сообщение
Не знаю, зачем вы отказались от использования "TBytes = array of Byte;" в пользу string (как было в старой программе bin->hex).
А где у меня в старой было Bytes = array of Byte;"?

Цитата:
Сообщение от BDA Посмотреть сообщение
Опять же, лучший подход сложно выбрать, не зная, куда выведет фантазия преподавателя по части выдумывания новых усложнений. Если он предложит еще парочку байтов выколоть, то устанешь кусочками читать.
Вот попробовал функцией , результат получается ;61Е7, а должен быть 69АС
при чём в функции и так делал ; Result :=Len; и так Result :=0; оба результата не верны.
Значит функцией не получается.
Изображения
Тип файла: jpg 3.JPG (37.6 Кб, 24 просмотров)

Последний раз редактировалось BDA; 11.11.2021 в 21:30.
sergey.serg-72 вне форума Ответить с цитированием
Старый 11.11.2021, 21:29   #25
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
а смещение не влияет на сумму?
Нет.
Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
а что в коде исправить adr2.?
В файле "Тест-3" байт 0E находится по адресу 2B, а не 2C. Перепроверьте в своем коде adr, adr2 и выставление position перед чтением.
Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
А где у меня в старой было Bytes = array of Byte;"?
В старой апрельской программе.
Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
при чём в функции и так делал ; Result :=Len; и так Result :=0; оба результата не верны.
Так и не надо редактировать Init.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Старый 11.11.2021, 21:56   #26
sergey.serg-72
Форумчанин
 
Регистрация: 12.03.2019
Сообщений: 376
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
В старой апрельской программе.
Так это когда было, я забыл давно, что там , делалось и как.

Цитата:
Сообщение от BDA Посмотреть сообщение
В файле "Тест-3" байт 0E находится по адресу 2B, а не 2C. Перепроверьте в своем коде adr, adr2 и выставление position перед чтением.
Блин, я уже запутался в каком коде, вроде и 2В выставлять, но результат не тот.

Сейчас вот новый код, но он в ошибку уходит, не компилируется .

Код:
 function CRC16CCITT(P: PChar; Len,Init: Word): Word;
var
i, j: Integer;
begin
Result :=Init;
for i := 0 to Len - 1 do
begin
if i = $2B then
continue;

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 $1021
else
Result := Result shl 1;
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
const Adr=$02b-$0;  Adr2=$02D-$05E;
Var
crc,W: Word;
Buffer,Buffer2,F: String;
fs: TFileStream;
Begin
edit2.Clear;
edit4.Clear;
edit5.Clear;
OpenDialog1.Filter:='BIN (*.bin)|*.bin';
with OpenDialog1 do
if Execute then
begin
fs:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);
Fs.Position:=$05E;
Fs.Read(w,2);
w:=swap(w );
edit4.Text:=IntToHex(w,2);

Fs.Position:=$02B;
SetLength(Buffer, Adr);
Fs.Read(Buffer[1],Adr);

Fs.Position:=$02D;
SetLength(Buffer2, Adr2);
Fs.Read(Buffer2[1],Adr2);

crc := CRC16CCITT(PChar(Buffer2), Adr2, CRC16XMODEM(PChar(Buffer1), Adr1, 0));

edit2.Text :=IntToHex(crc, 2);
Fs.free;
end;
end;

ругается на эту строку, не пойму, в чём проблема?

Код:
 crc := CRC16CCITT(PChar(Buffer2), Adr2, CRC16XMODEM(PChar(Buffer1), Adr1, 0));
Цитата:
Сообщение от BDA Посмотреть сообщение
Так и не надо редактировать Init.
Ни чего не надо редактировать, всё оказалось проще не куда.
BDA, Вы изначально были правы , надо было, в функцию добавить :
Код:
begin
if i = $02B then
continue;
И второе надо было адрес полностью :
Код:
const Adr=$05E-$0;
Всё и код старый прекрасно справляется с поставленной задачей.
Вот я тормоз, перекурил, отдохнул и меня осенило сразу.

Вот полный, рабочий код :
Код:
{$R *.dfm}
function CRC16XMODEM(P: PChar; Len: Word): Word;
var
i, j: Integer;
begin
Result :=0;
for i := 0 to Len - 1 do
begin
if i = $02B then
continue;
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 $1021
else
Result := Result shl 1;
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
const Adr=$05E-$0;
Var
crc,W: Word;
Buffer: String;
fs: TFileStream;
Begin
edit2.Clear;
edit4.Clear;
edit5.Clear;
OpenDialog1.Filter:='BIN (*.bin)|*.bin';
with OpenDialog1 do
if Execute then
begin
fs:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);
if fs.Size > 96 then
begin
ShowMessage('Некорректный  размер  файла ( Строго 96 байт )  !');
Fs.free;
exit;
end
else
begin
edit5.Text:=ExtractFileName(OpenDialog1.FileName);
label2.Caption:= 'Size :'+' ' +IntToStr(fs.Size)+ ' ' + ' '+'Byte';
Fs.Position:=$05E;
Fs.Read(w,2);
w:=swap(w );
edit4.Text:=IntToHex(w,2);

Fs.Position:=$0;
SetLength(Buffer, Adr);
Fs.Read(Buffer[1],Adr);
crc :=CRC16XMODEM(PChar(Buffer),Length(Buffer));
edit2.Text :=IntToHex(crc, 2);
Fs.free;
end;
end;
end;

Делов оказалось на 5 минут и в 2 строки. А воды море вышло.....

Всё отлично получилось и просто. Огромное спасибо BDA за помощь.

Цитата:
Сообщение от BDA Посмотреть сообщение
Не знаю, зачем вы отказались от использования "TBytes = array of Byte;" в пользу string (как было в старой программе bin->hex).

Да, BDA Вы правы оказались поднял старые архивы и нашёл.

Можно и так :
Код:
 type
  TBytes = array of Byte;

Код:
var
b: TBytes;
Код:
SetLength(b, Adr);
Да , можно без string было обойтись Byte.
Сейчас и этот вариант отработаю.
Подзабывается старое, хорошо , что напомнили.

Ещё раз огромная благодарность BDA за помощь !.
Вложения
Тип файла: rar Тест -3.rar (171.6 Кб, 3 просмотров)
Тип файла: rar Тест -3- полный с контролеой.rar (217 байт, 4 просмотров)

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

Ну хорошо, что разобрались.
Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
ругается на эту строку, не пойму, в чём проблема?
Но с ошибками компилятора лучше научиться разбираться самому, чем ждать ответов. У вас переменные и функция по-другому названы, вот компилятор и не находит их.
И стоит проверять на неравенство, чтобы и меньшие по объему файлы не пропускать:
Код:
if fs.Size <> 96 then
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 13.11.2021 в 03:54.
BDA на форуме Ответить с цитированием
Старый 13.11.2021, 06:21   #28
sergey.serg-72
Форумчанин
 
Регистрация: 12.03.2019
Сообщений: 376
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Но с ошибками компилятора лучше научиться разбираться самому, чем ждать ответов. У вас переменные и функция по-другому названы, вот компилятор и не находит их.
И стоит проверять на неравенство, чтобы и меньшие по объему файлы не пропускать:
Да, сейчас посмотрел, это факт не внимательность.

BDA, Вы наверное пророк? препод приматался к функции, говорит что она работает только, если с 0 адреса подсчитывать :
Код:
function CRC16XMODEM(P: PChar; Len: Word): Word;
var
i, j: Integer;
begin
Result :=0;
for i := 0 to Len - 1 do
begin
if i = $02B then
continue;
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 $1021
else
Result := Result shl 1;
end;
end;
end;
А, если как он сказал начать отчёт не с 0, адреса, а с 20 скажем?

конструкция перестаёт работать нормально
Код:
procedure TForm1.Button1Click(Sender: TObject);
const Adr=$05E-$0;
Var
$20
пытался изменить адрес в константе, на $05E- $20;

Подсчитывает неправильно из чего сделал вывод: что проблема в функции function CRC16XMODEM(P: PChar; Len: Word): Word;
Изменение адреса в константе и в коде не помогает.

Отсюда вопросы : 1)как изменить функцию, чтоб при заданном адресе скажем с 10, или с20 адреса функция правильно подсчитывала ? 2) вопрос у нас есть константа, это фиксированный адрес для массива const Adr=$05E-$0; а можно ли сделать так, чтоб адрес задавался в ручную, скажем из edit ?
Сижу, всю ночь, так и не разобрался, в инете не нашёл ни чего, такое делать, раньше не приходилось.

Почитал, что то типа так делают :b := Strtoint('$' + Edit4.Text);
FS.Position :=Strtoint('$' + edit5.Text) ;
Но не понятно как задавать адрес с10 скажем по 100 как в tdit вводить const Adr=$05E-$0;?
Мне кажется это не реально. Весь мозг сломал, не могу даже подступится.

Слёзно прошу объяснить.

p.s

Тему тогда продолжим, ведь всё относится к теме.
Изображения
Тип файла: jpg 1.JPG (43.7 Кб, 17 просмотров)

Последний раз редактировалось sergey.serg-72; 13.11.2021 в 06:26.
sergey.serg-72 вне форума Ответить с цитированием
Старый 13.11.2021, 21:25   #29
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Код:
function CRC16XMODEM(P: PChar; Len: Word; skip_i: Integer): Word;
var
  i, j: Integer;
begin
  Result := 0;
  for i := 0 to Len - 1 do
  begin
    if i = skip_i then
      continue;

...

begin_addr := // забрать из эдита
end_addr := // забрать из эдита
// проверить, что 0 <= begin_addr <= end_addr < 96
skip_addr := // забрать из эдита

buf_len := end_addr - begin_addr + 1;
Fs.Position := begin_addr;
SetLength(buffer, buf_len);
Fs.Read(buffer[1], buf_len);
crc := CRC16XMODEM(PChar(buffer), buf_len, skip_addr - begin_addr);
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Старый 13.11.2021, 22:30   #30
sergey.serg-72
Форумчанин
 
Регистрация: 12.03.2019
Сообщений: 376
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
function CRC16XMODEM(P: PChar; Len: Word; skip_i: Integer): Word;
var
i, j: Integer;
begin
Result := 0;
for i := 0 to Len - 1 do
begin
if i = skip_i then
continue;

...

begin_addr := // забрать из эдита
end_addr := // забрать из эдита
// проверить, что 0 <= begin_addr <= end_addr < 96
skip_addr := // забрать из эдита

buf_len := end_addr - begin_addr + 1;
Fs.Position := begin_addr;
SetLength(buffer, buf_len);
Fs.Read(buffer[1], buf_len);
crc := CRC16XMODEM(PChar(buffer), buf_len, skip_addr - begin_addr);

BDA я чуток не допонял это всё функция ? или к функции только это относится?
Код:
begin_addr := // забрать из эдита
end_addr := // забрать из эдита
// проверить, что 0 <= begin_addr <= end_addr < 96
skip_addr := // забрать из эдита

А вот эта часть кода. уже к процедуре?
Код:
 buf_len := end_addr - begin_addr + 1;
Fs.Position := begin_addr;
SetLength(buffer, buf_len);
Fs.Read(buffer[1], buf_len);
crc := CRC16XMODEM(PChar(buffer), buf_len, skip_addr - begin_addr);[/QUOTE]
что то я потерялся совсем, вроде понятно, а вроде не понятно совсем.

Как я понимаю что skip_addr := // забрать из эдита это должно быть в функции, а вот

begin_addr := // забрать из эдита
end_addr := // забрать из эдита в процедуре, а зачем три едита? двумя не обойтись?

Дальше вот эта строка :// проверить, что 0 <= begin_addr <= end_addr < 96 это в функции должна быть, или в процедуре?

Вот делаю так : но не в функции. не в процедуре компилятор ругается

Код:
 skip_i:=Strtoint('$' + Edit3.Text);
не нравится компилятору skip_i:

С функцией кажется разобрался наверное так :
Код:
 function CRC16XMODEM(P: PChar; Len: Word; skip_i: Integer): Word;
var
i, j: Integer;
begin
Result := 0;
for i := 0 to Len - 1 do
begin
if i = skip_i then
continue;
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 $1021
else
Result := Result shl 1;
end;
end;
end;
А вот дальше не понимаю этого ;
Код:
begin_addr := // забрать из эдита
end_addr := // забрать из эдита
// проверить, что 0 <= begin_addr <= end_addr < 96
skip_addr := // забрать из эдита

buf_len := end_addr - begin_addr + 1;

Последний раз редактировалось BDA; 19.11.2021 в 18:47.
sergey.serg-72 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 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