![]() |
![]() ![]() ![]() | |
|
Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|| Форумы Здесь вы можете задать свой вопрос и наверняка получите ответ |
ЧАТ |
Место для общения :)
Орешник
Коллекция курьезных вопросов из форумов
| ||
![]() | ||
|
Страницы: 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 версия для печати
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)
|
![]() ![]() ![]() |