Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник
Коллекция курьезных вопросов из форумов
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »
Страницы: 1 2 3 4 5

Алгоритм контрольной суммы Флетчера


cryptologic ©   (30.03.21 22:16[40]

uint32_t
> cryptologic ©   (30.03.21 20:32) [37]


Выше упомянутая функция это оптимизированная.

Это не оптимизированная  функция. Ее проверил работает?
Но вот по ней делаю на Delphi и результат  не выходить  три варианта испробовал ничего не выходит...  у меня возникает подозрение, что косяки вылазит на действиях с бинарной математикой  не корректно складываются числа, может это из-за супернового процессора  
Получается (sum2 shl 16) or sum1; какие бы значения в sum2 небыли после or в старших байтах остаются только 00 выход всегда выглядит так  [00XX]  ... вообще не пойму как он так складывает?  Проц. супер новый Ryzen 9 5950X или косяки в компиляторе.

fletcher32(const uint16_t *data, size_t len)
{
  uint32_t sum1 = 0;
  uint32_t sum2 = 0;

  for(int index = 0; index < len; ++index ) {
     sum1 = (sum1 + data[index]) % 0xffff;
     sum2 = (sum2 + sum1) % 0xffff;
  }
  return (sum2 << 16) | sum1;
}


KSergey ©   (31.03.21 06:42[41]

> cryptologic ©   (30.03.21 20:44) [39]
>
> Я так понимаю, что данные должны подаваться таким образом

Да, я про это уже написал - верный вариант 1 из KSergey ©   (30.03.21 09:29) [32]


KSergey ©   (31.03.21 06:44[42]

> cryptologic ©   (30.03.21 22:16) [40]
> Выше упомянутая функция это оптимизированная.
>
> Это не оптимизированная  функция. Ее проверил работает?

Вы уж как-нибудь сами проверяйте, я выше давал ссылку на онлайн-компилятор, там всё это можно и легко.


KSergey ©   (31.03.21 07:26[43]

Пробовать здесь:
https://onlinegdb.com/HkGecdWr_

type
   PUInt16 = ^UInt16;

function fletcher32(data: PUInt16; len: UInt32): UInt32;
var
      c0, c1: UInt32;
      i: UInt32;
begin
       c0 := 0;
       c1 := 0;
       while len >= 360 do
       begin
              for i := 1 to 360 do
              begin
                      c0 := c0 + data^;
                      c1 := c1 + c0;
                      Inc(data);
              end;
              c0 := c0 mod 65535;
              c1 := c1 mod 65535;
              len := len - 360;
      end;
      for i := 1 to len do
      begin
              c0 := c0 + data^;
              c1 := c1 + c0;
              Inc(data);
      end;
      c0 := c0 mod 65535;
      c1 := c1 mod 65535;
      {Result}fletcher32 := (c1 shl 16) or c0;
end;

function fletcher32(data: AnsiString): UInt32;
var
   len: UInt32;
begin
   len := 3;   // TODO: сделать верный алгоритм вычисления len через длину переданной строки
   {Result}fletcher32 := fletcher32(PUInt16(PAnsiChar(data)), len)
end;

begin
 writeln (fletcher32('abcde'));
end.


KSergey ©   (31.03.21 07:30[44]

Кстати, что там будет для строк, когда len > 360 - не проверял.


cryptologic ©   (31.03.21 21:38[45]


> KSergey ©   (31.03.21 07:30) [44]
> Кстати, что там будет для строк, когда len > 360 - не проверял.
>


Сам не знаю,  то же не проверял..

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


cryptologic ©   (01.04.21 06:47[46]

Опубликовал модуль:  
https://github.com/superbot-coder/additional_modules/blob/master/Fletcher.pas

Пока только с функциями без оптимизации, позже после дополнительной проверки добавлю с оптимизированными функциями.


cryptologic ©   (01.04.21 07:03[47]


> cryptologic ©   (30.03.21 20:44) [39]


В действительности последний блок данных при не четном количестве данных заполняется
так 'abcde' - > Uint16 [ab][cd][0e] или [abcd][000e] ,  а не так как я предполагал [ab][cd][e0] или Uint32 [abcd][e000]... Просто все подгоняют результаты под статью в википедии, но никто не усомнился, а что если в самой википедии неправильно?


cryptologic ©   (01.04.21 07:17[48]


> cryptologic ©   (01.04.21 07:03) [47]
>

Я когда то в бурные годы молодости взламывал VPN`ки (причем удачно) и для этого копался в RFC стандартах и тоже находил кучу несоответствий описанных в RFC с действительностью, там порой так размыто и не определенно описаны стандарты, что если делать как написано, то никoгда в жизни не получить желаемого результата - это будет выглядеть как попытка натянуть сову на глобус.


KSergey ©   (01.04.21 07:38[49]

> cryptologic ©   (01.04.21 07:03) [47]
> В действительности последний блок данных при не четном количестве данных заполняется
> так 'abcde' - > Uint16 [ab][cd][0e]

Не понятно почему 0 и е поменяны местами, а все остальное - нет.
Явно же все поменяно местами, это ж Intel


cryptologic ©   (01.04.21 11:52[50]


> KSergey ©   (01.04.21 07:38) [49]
> > cryptologic ©   (01.04.21 07:03) [47]
> > В действительности последний блок данных при не четном
> количестве данных заполняется
> > так 'abcde' - > Uint16 [ab][cd][0e]
>
> Не понятно почему 0 и е поменяны местами, а все остальное
> - нет.
> Явно же все поменяно местами, это ж Intel


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


KSergey ©   (01.04.21 13:05[51]

Мусор там, конечно, будет
Просто при обращении через PUInt16 нам везёт, т.к. PAnsiChar() гарантированно возвращает строку с 0 байтом на конце.

А вот обращение по PUint32 (ну в смысле каст к такому указателю) дас нам тут мусор, конечно, или вообще вылет за границы памяти.

> cryptologic ©   (01.04.21 06:47) [46]
>
> Опубликовал модуль:  
> https://github.com/superbot-coder/additional_modules/blob/master/Fletcher.pas


   sum1 := (sum1 + PUint32(AStrData)^) mod $FFFFFFFF;


cryptologic ©   (01.04.21 17:32[52]


> KSergey ©   (01.04.21 13:05) [51]
> Мусор там, конечно, будет
> Просто при обращении через PUInt16 нам везёт, т.к. PAnsiChar()
> гарантированно возвращает строку с 0 байтом на конце.


Смотрел в Uint32 и в Uint64  ратина одна чисто, может просто всегда везет и область памяти за пределами строки чистая или же так отрабатывает компилятор не дает взять данные за пределами строки.


cryptologic ©   (01.04.21 17:33[53]


> KSergey ©   (01.04.21 13:05) [51]


> sum1 := (sum1 + PUint32(AStrData)^) mod $FFFFFFFF;
>
>

А что тут не так?


cryptologic ©   (01.04.21 17:35[54]

Кстати не я только сомневался в правильность кода, вот еще поднималась дискуссия
https://stackoverflow.com/questions/40270450/correctness-of-fletcher32-checksum-algorithm


cryptologic ©   (01.04.21 17:47[55]


> KSergey ©   (01.04.21 13:05) [51]
> Мусор там, конечно, будет


Я ни водном примере в не нашел кто бы заморачивался и чистил конец последний болк получаемых данных при не четных входных данных


KSergey ©   (02.04.21 07:11[56]

> cryptologic ©   (01.04.21 17:47) [55]
> Я ни водном примере в не нашел кто бы заморачивался и чистил
> конец последний болк получаемых данных при не четных входных данных

Вывод прост: примеры делают не очень квалифицированные люди.


KSergey ©   (02.04.21 07:15[57]

>  cryptologic ©   (01.04.21 17:33) [53]
> > sum1 := (sum1 + PUint32(AStrData)^) mod $FFFFFFFF;

Возьмите бумагу в клеточку
Распишите как в памяти выглядит побайтно строка "abcde"
далее двигая указатель в выражении PUint32(AStrData)^ обводите те группы байтов, которые будут считываться из памяти. И вам всё станет понятно.

Надо всегда помнить, что при обращении за пределы выделенного куска памяти - всё что угодно может происходить. И мусор, и access violation и все что угодно.


KSergey ©   (02.04.21 07:19[58]

>  cryptologic ©   (01.04.21 17:32) [52]
> Смотрел в Uint32 и в Uint64  ратина одна чисто, может просто всегда везет и область памяти за пределами строки чистая
> или же так отрабатывает компилятор не дает взять данные за пределами строки.

В простейшем модельном примере, да еще в дебаге - это совсем не то, что в релизе и реальной программе.
Мне лень подбирать какой-то демонстрационный пример, с ходу ведь не придумаешь как так заставить появиться мусору.
Попробуйте, например, что-то такое, вдруг повезёт:

str := "abcfeyz";
SetLength(str, 5);


KSergey ©   (02.04.21 09:23[59]

> KSergey ©   (02.04.21 07:11) [56]
>
> > cryptologic ©   (01.04.21 17:47) [55]
> > Я ни водном примере в не нашел кто бы заморачивался и
> чистил
> > конец последний болк получаемых данных при не четных входных
> данных
>
> Вывод прост: примеры делают не очень квалифицированные люди.
>

Впрочем, тут бы пример, конечно, ссылку где такое.


Страницы: 1 2 3 4 5 версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо