Мастера 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 ©   (02.04.21 23:46[60]


> KSergey ©   (02.04.21 07:19) [58]


Но вот по сути это же хакерский метод указать длину строки  10 байт а пытаться прочитать гигабайт, а еще можно залезть в адресное пространство соседнего процесса и считать там приватный блок данных, например с ключами шифрования - это ничего не напоминает?
Сейчас на современных процессорах уже внедряются подобные защиты как от Spectre, Meltdown,  переполнения буфера и попытка чтение данных за пределами адресного пространстве, то что защита от переполнения буфера уже точно реализована, а вот второе нужно поинтересоваться как называется и вообще реализована ли в природе.

Это не освобождает программиста самостоятельно контролировать "критический" код, и тут я с вами согласен, что "зачистку" последнего блока данных стоит сделать, ноя не согласен с методом, который вы предлагаете SetLength()  Т.е. если у меня входные данные строка то вы предлагаете ее изменить увеличив нулями, а это вовсе не хорошо, т.к. в коде может потребоваться использовать параметр ее длины.. или еще, что-нибудь  

я  предлагаю такой код, основанный на том что бы почистить только последний блок

function Fletcher64(AStrData: PAnsiChar): UInt64;
var
 sum1, sum2: UInt64;
 sum0, len, i: UInt32;
 rem: Byte; // Remainder of division
Type
 PUint32 = ^Uint32;
begin
 sum1 := 0;
 sum2 := 0;
 len := Length(PAnsiChar(AStrData));
 // Uint32 размер чтения входящего блока
 rem  := (len mod SizeOf(sum0));

 // Определение четности
 if rem = 0 then len := len div 4
 else Len := (Len div 4) + 1;

 for i := 1 to len do
 begin
   sum0  := PUint32(AStrData)^;
   // Определяем, что блок последний
   if i = len then
   begin
     //сдвигает байты влево, а затем обратно что бы почисть от возможного мусора
     case rem of
       1: sum0 := (sum0 shl 24) shr 24;
       2: sum0 := (sum0 shl 16) shr 16;
       3: sum0 := (sum0 shr 8) shr 8;
     end;
   end;
   sum1 := (sum1 + sum0) mod $FFFFFFFF;
   sum2 := (sum2 + sum1) mod $FFFFFFFF;
   Inc(PUint32(AStrData));
 end;
 Result := (sum2 shl 32) or sum1;

end;


cryptologic ©   (02.04.21 23:51[61]


> cryptologic ©   (02.04.21 23:46) [60]


сорри...

в строке 29 ошибочка   3: sum0 := (sum0 shr 8) shr 8;
имелось виду так sum0 := (sum0 shl 8) shr 8;


manaka ©   (03.04.21 16:32[62]

А вам не кажется, что вы занимаетесь тем, что запрещено правилами форума?

Запрещается:
6. Публиковать или искать серийные номера, коды а также алгоритмы взлома того или иного программного обеспечения


KSergey ©   (06.04.21 08:29[63]

> cryptologic ©   (02.04.21 23:46) [60]
> Но вот по сути это же хакерский метод указать длину строки
>  10 байт а пытаться прочитать гигабайт

> это ничего не напоминает?

Напоминает.
Криворукость глючного софта.


KSergey ©   (06.04.21 08:33[64]

> sum0  := PUint32(AStrData)^;

Нельзя так. Просто нельзя.
Именно на таком вот криворуком говнокоде под девизом "а у меня работает!" потом и резвятся разные "хакеры".

Если не хочется делать копию входного буфера для "добивания" до нужного числа байтов - то надо корректно обыграть обработку вычитывания финальных байтов, раз уж вот это вот всё началось:


>     // Определяем, что блок последний
>     if i = len then
>     begin
>       //сдвигает байты влево, а затем обратно что бы почисть
> от возможного мусора
>       case rem of
>


KSergey ©   (06.04.21 08:36[65]

PS
Удивительно: рядом бурно обсуждаются какие-то сериалы и прочие убийство времени впустую, а в этой осмысленной в общем-то ветке - тишина.

Скажите, что я не понимаю?


cryptologic ©   (08.04.21 06:49[66]


> KSergey ©   (06.04.21 08:33) [64]
> > sum0  := PUint32(AStrData)^;


Может так и не льзя, я не знаю как это будет выглядеть на ассемблере, но именно такой код дает более высокую производительность где то на 30% быстрее чем просто sum0  := PUint32(AStrData)  - измерял эмпирическим путем.
> Если не хочется делать копию входного буфера для "добивания"
> до нужного числа байтов - то надо корректно обыграть обработку
> вычитывания финальных байтов, раз уж вот это вот всё началось:
>
>
>
> >     // Определяем, что блок последний
> >     if i = len then
> >     begin
> >       //сдвигает байты влево, а затем обратно что бы почисть
> > от возможного мусора
> >       case rem of
> >


function Fletcher64(AStrData: PAnsiChar): UInt64;
var
 sum1, sum2: UInt64;
 sum0, len, i: UInt32;
 rem, shift: Byte; // Remainder of division
Type
 PUint32 = ^Uint32;
begin
 sum1 := 0;
 sum2 := 0;
 len := Length(PAnsiChar(AStrData));
 // Uint32 размер чтения входящего блока 4 байта
 rem   := (len mod 4);
 // (4 байта - rem остаток ) * 8 bit
 shift := (4 - rem) * 8;

 // Определение четности
 if rem = 0 then len := len div 4
 else Len := (Len div 4) + 1;

 for i := 1 to len do
 begin
   sum0  := PUint32(AStrData);
   // Определяем, что блок последний
   // Сдвигает байты влево, а затем обратно, что бы почисть от возможного
   if i = len then sum0 := (sum0 shl shift) shr shift;
   sum1 := (sum1 + sum0) mod $FFFFFFFF;
   sum2 := (sum2 + sum1) mod $FFFFFFFF;
   Inc(PUint32(AStrData));
 end;

 Result := (sum2 shl 32) or sum1;

end;


cryptologic ©   (08.04.21 07:14[67]


> cryptologic ©   (08.04.21 06:49) [66]


Поторопился с кодом
Имелось ввиду как то так..

function Fletcher64(AStrData: PAnsiChar): UInt64;
var
 sum1, sum2: UInt64;
 sum0, len, i: UInt32;
 rem, shift: Byte; // Remainder of division
Type
 PUint32 = ^Uint32;
begin
 sum1  := 0;
 sum2  := 0;
 shift  := 0;
 len := Length(PAnsiChar(AStrData));
 // Uint32 размер чтения входящего блока 4 байта
 rem   := (len mod 4);
 // Определение четности
 if rem = 0 then len := len div 4
 else
 begin
   shift := (4 - rem) * 8; // если rem <> 0
   Len := (Len div 4) + 1;
 end;

 for i := 1 to len do
 begin
   sum0  := PUint32(AStrData)^;
   sum0  := sum0;
   // Определяем, что блок последний
   // Сдвигает байты влево, а затем обратно,
   // что бы почисть от возможного мусора
   if (i = len) then sum0 := (sum0 shl shift) shr shift;
   sum1 := (sum1 + sum0) mod $FFFFFFFF;
   sum2 := (sum2 + sum1) mod $FFFFFFFF;
   Inc(PUint32(AStrData));
 end;
 Result := (sum2 shl 32) or sum1;
end;


cryptologic ©   (08.04.21 07:20[68]

Ну можно еще в строку 30
добавить дополнительное условие    
if (i = len) and (rem <> 0) then sum0 := (sum0 shl shift) shr shift;

То есть избавимся в цикле от оператора "case" - он точно был полный зашквар, зато было наглядно.


KSergey ©   (08.04.21 07:22[69]

> > > sum0  := PUint32(AStrData)^;
> дает более высокую производительность
> где то на 30% быстрее чем просто sum0  := PUint32(AStrData)

Это вот не понял. Это совершенно разные же операции.
А в свете разговоров про скорость - даже не понимаю где тут описка.


KSergey ©   (08.04.21 07:35[70]

> cryptologic ©   (08.04.21 07:14) [67]
>   for i := 1 to len do
>   begin
>     sum0  := PUint32(AStrData)^;
>     sum0  := sum0;   <----- !!!!????
>     // Определяем, что блок последний


Впрочем, я люблю надёжный код; лучше 2 раза присвоить, это надёжнее. Я тоже так порой делаю, для надёжности. ;)

Что по поводу вот этого
>     sum0  := PUint32(AStrData)^;
то я всегда предлагаю в таком случае взять листок бумаги в клетку, нарисовать в клеточках строку (байты в памяти), жирно выделить границу выделенной под строку памяти. После чего обводить по 4 клетки (в данном случае) вычитываемых данных и понять, что тут не так и что фактически вычитывается.
Если человек не понимает - я расстаюсь с ним без сожалению. Поймёт - велкам, будет смысл дальше с ним сотрудничать.
Объяснить что тут и как я, конечно могу, но штука в том, что для осознания и принятия этой штуки требуется определённое время, я не вижу для себя смысла это время ждать и наблюдать.


cryptologic ©   (08.04.21 08:46[71]


> >     sum0  := sum0;   <----- !!!!????


Это было для отладки я на этом шаге "бряк" устанавливал, потом забыл удалить  .


cryptologic ©   (08.04.21 10:03[72]


> Что по поводу вот этого
> >     sum0  := PUint32(AStrData)^;


А в чем криминал? Здесь все правильно - Это получается сокращенная форм записи, только без дополнительной переменной как у вас..  Возможно это не оптимально так как это стоит в цикле и компилятору каждый вызов придется приводить один тип к другому.

Переделал код

{------------------------------- Fletcher64 -----------------------------------}
function Fletcher64(AStrData: PAnsiChar): UInt64;
Type
 PUint32 = ^Uint32;
var
 sum1, sum2: UInt64;
 sum0, len, i: UInt32;
 rem, shift: Byte; // Remainder of division
 Pu32 : PUint32;

begin
 sum1  := 0;
 sum2  := 0;
 shift := 0;
 len := Length(PAnsiChar(AStrData));
 // Uint32 размер чтения входящего блока 4 байта
 rem   := (len mod 4);
 Pu32 := PUint32(AStrData);

 // Определение четности
 if rem = 0 then len := len div 4
 else
 begin
   shift := (4 - rem) * 8; // если rem <> 0
   Len := (Len div 4) + 1;
 end;

 for i := 1 to len do
 begin
   sum0  := Pu32^; // PUint32(AStrData);
   // Определяем, что блок последний
   // Сдвигает байты влево, а затем обратно,
   // что бы почисть от возможного мусора
   if (i = len) and (rem <> 0) then sum0 := (sum0 shl shift) shr shift;
   sum1 := (sum1 + sum0) mod $FFFFFFFF;
   sum2 := (sum2 + sum1) mod $FFFFFFFF;
   //Inc(PUint32(AStrData));
   Inc(Pu32);
 end;

 Result := (sum2 shl 32) or sum1;

end;


cryptologic ©   (08.04.21 10:28[73]


> cryptologic ©   (08.04.21 10:03) [72]
>
> > Что по поводу вот этого
> > >     sum0  := PUint32(AStrData)^;
>


Вообще не знаю, почему, но оно по правильному  такая связка
  sum0  := PUint32(AStrData)^;
  inc(PUint32(AStrData))

не должно работать,  так как а где компилятор сохраняет инкрементное смещение указателя, если переменной указателя то и нету  как здесь:

Type
PUint32 = ^Uint32;
var
Pu32 : PUint32;

Pu32 := PUint32(AStrData);
Inc(Pu32);


Но каким то образом компилятор разруливает эту ситуацию..


cryptologic ©   (08.04.21 10:33[74]


> cryptologic ©   (08.04.21 10:28) [73]
>


Получается что и первый пример без переменной работает и второй с переменной указателя работает
Мне вообще интересно как  компилятор два эти примера реализует в машинном коде или на ассемблере


KSergey ©   (08.04.21 10:51[75]

> cryptologic ©   (08.04.21 10:03) [72]
> > >     sum0  := PUint32(AStrData)^;
> А в чем криминал?

Покажите фото листочка в клеточку, где вы всё разрисовали.
Без этого нет смысла продолжать разговор.


cryptologic ©   (08.04.21 11:44[76]


> KSergey ©   (08.04.21 10:51) [75]
> > cryptologic ©   (08.04.21 10:03) [72]
> > > >     sum0  := PUint32(AStrData)^;
> > А в чем криминал?
>
> Покажите фото листочка в клеточку, где вы всё разрисовали.
>


Причем тут листочек в клеточку? Вы же то же самое делаете:
function fletcher32(data: PUInt16; len: UInt32): UInt32; - у вас заголовок объявлен с типизированной переменой-указателем, затем вы в функцию передаете другой указатель другого типа  fletcher32(PUInt16(PAnsiChar(data)), len) то есть, что происходит?  Происходи то что один тип указателя был преобразован в другой тип, а точнее указатель Data получил адрес начала строки или начало блока данных..  Такое можно описать аналогиyто Data := PUint16(PAnsiChar('abcde'));  Затем вы присваиваете разыменовываете указатель c0 := c0 + data^; и присваиваете данные на которые указывает указатель
А теперь сократим эти действия с0 := c0 + PUint16(PAnsiChar('abcde'))^  - и получаем тоже самое как в вашем коде только напрямую минуя типизированную переменную Data
На какие неправильные данные должно указывать?


cryptologic ©   (08.04.21 12:12[77]


> KSergey ©   (08.04.21 10:51) [75]
> > cryptologic ©   (08.04.21 10:03) [72]
> > > >     sum0  := PUint32(AStrData)^;
> > А в чем криминал?
>
> Покажите фото листочка в клеточку, где вы всё разрисовали.
>
> Без этого нет смысла продолжать разговор.


А на бумажках ничего давно ничего не черчу.. Хоть есть и поговорка верна, что тупой карандаш лучше острой памяти.  Просто предпочитаю текстовый блокнот и там творю всякие "художества".  

[a]  [b]  [c]   [d]   [e]
97   98  99   100  101
И вот как читаются данные из памяти fletcher64 блок чтения 32бит                                                                                                        
                      десятич.                                                                       [d   c   b   a]  
Интерация 1: 1684234849  01100100 01100011 01100010 01100001:  100  99 98 97
Интерация 2  0000000101                                                               :         0  0  0 e


KSergey ©   (08.04.21 12:13[78]

> cryptologic ©   (08.04.21 11:44) [76]
> Причем тут листочек в клеточку? Вы же то же самое делаете:

Без выходного пособия.
Удачи!


cryptologic ©   (08.04.21 12:24[79]


> KSergey ©   (08.04.21 12:13) [78]
> > cryptologic ©   (08.04.21 11:44) [76]
> > Причем тут листочек в клеточку? Вы же то же самое делаете:
>
>
> Без выходного пособия.
> Удачи!
>
>


Сорян дружище извини, что потратил твое драгоценное время...

> KSergey ©   (06.04.21 08:36) [65]
> PS
> Удивительно: рядом бурно обсуждаются какие-то сериалы и
> прочие убийство времени впустую


Можете и дальше обсуждать, что обсуждается в соседних ветках я вас в принципе не заставлял ничего делать, сами хотели отвечали, хотели не отвечали...


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

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

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







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


Наверх

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