Форум программистов CodeGuru
18 Сентябрь 2018, 23:07:53 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
Новости:
 
   Начало   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: Интересный пример для расчёта контрольной суммы.  (Прочитано 18881 раз)
0 Пользователей и 1 Гость смотрят эту тему.
ATAMAN200
Интересующийся
**
Офлайн Офлайн

Сообщений: 29


Просмотр профиля
« : 05 Октябрь 2010, 19:12:07 »

Цитирую из http://rfc2.ru/1071.rfc
Цитировать
Приведенный ниже пример на языке C показывает расчет контрольной суммы с использованием внутреннего цикла сложения 16-битовых значений в 32-битовый «аккумулятор
Код:
in 6
    {
        /* Расчет контрольной суммы Internet для count байтов,
         * начиная с addr.
         */
     register long sum = 0;

     while( count > 1 )  {
        /*  Внутренний цикл */
            sum += * (unsigned short) addr++;
            count -= 2;
    }

        /*  Прибавляем байт переноса, если он есть */
    if( count > 0 )
            sum += * (unsigned char *) addr;

        /*  поместим 32-битовую сумму в 16 битов */
    while (sum>>16)
        sum = (sum & 0xffff) + (sum >> 16);

    checksum = ~sum;
}

но это ладно вроди надо обявить переменные которые выше не объявлены
Код:
#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
register long sum = 0;
register long count = 0xfa55aa67;
     while( count > 1 )  {
        /*  Внутренний цикл */
            sum += * (unsigned short) addr++;
            count -= 2;
    }

        /*  Прибавляем байт переноса, если он есть */
    if( count > 0 )
            sum += * (unsigned char *) addr;

        /*  поместим 32-битовую сумму в 16 битов */
    while (sum>>16)
        sum = (sum & 0xffff) + (sum >> 16);

   register long checksum = ~sum;

return 0;
}


может так но вот это как понять "* начиная с addr." начиная с какого addr и чем должна быть эта addr функцией, переменной?
« Последнее редактирование: 05 Октябрь 2010, 19:15:21 от ATAMAN200 » Записан
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #1 : 06 Октябрь 2010, 18:42:12 »

Я так понимаю, addr - это указатель на буфер с данными. А count - количество байт в буфере. Т.е. декларация функции с приведенным кодом могла бы выглядеть так:

Код:
long GetInternetChecksum(void *addr, int count);

Адрес буфера, для которого надо рассчитать контрольную сумму, передаем через первый параметр, количество байт в буфере - во втором. Только надо помнить, что размер буфера должен быть кратен 2-м, "хвост" буфера надо заполнить нулями. Если контрольная сумма рассчитывается для UDP-пакета, то его поле контрольной суммы - тоже заполняем нулями.


И еще ремарка.
Сомнения по поводу кода.
Код:
     while( count > 1 )  {
        /*  Внутренний цикл */
            sum += * (unsigned short) addr++;
            count -= 2;
    }

Как минимум опечатка в
Код:
            sum += * (unsigned short) addr++;

Имхо, должно быть
Код:
            sum += * (unsigned short *) addr++;

т.е. addr надо приводить к указателю.

Еще, addr++ будет увеличивать addr на размер адресуемого типа данных. При этом, если addr будет типа void *, то компилятор ругнется. Если же addr будет, скажем, типа char *, то алгоритм будет работать неправильно, поскольку addr будет увеличиваться на 1, а строка "count -= 2;" как бы намекает, что и адрес надо на 2 увеличивать.
« Последнее редактирование: 06 Октябрь 2010, 19:16:48 от 3V » Записан

ATAMAN200
Интересующийся
**
Офлайн Офлайн

Сообщений: 29


Просмотр профиля
« Ответ #2 : 06 Октябрь 2010, 22:40:00 »

На самом дели я разбираю всего навсего алгоритм по вычеслению контрольнои суммы udp пакета.
Этот алгоритм был придуман и создан америкосами давным давно и мы не можем дать на него ответ?
Вот нашол скрипт:

#include "stdafx.h"
#include <iostream>
#include "conio.h"
using namespace std;
int main()
{
int sum, oddbyte;
short answer;
unsigned short ptr[2] = {0xffaa44542f, 0xdadaf446};
int nbytes = 256;
 
    sum = 0;
 
    while ( nbytes > 1 ) {
 
           sum += ptr ++;
 
           nbytes -= 2;
 
    }
 
 
 
    if ( nbytes == 1 ) {
 
          int oddbytes = 0;
 
           * (( unsigned char *) &oddbyte ) = * (unsigned char *) ptr;
 
           sum += oddbyte;
 
    }
 
 
 
    sum = ( sum >> 16 ) + ( sum & 0xFFFF);
 
    sum += (sum >> 16 );
 
    answer=~sum;
cout << hex << answer;
    getch();
}

это обидно.
Записан
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #3 : 07 Октябрь 2010, 00:18:27 »

На самом дели я разбираю всего навсего алгоритм по вычеслению контрольнои суммы udp пакета.
Этот алгоритм был придуман и создан америкосами давным давно и мы не можем дать на него ответ?

Не понял, что значит "дать ответ"  Улыбка

Вот нашол скрипт:

Какой-то странный код.
Как минимум здесь:

Код:
sum += ptr ++;

компилятор должен ругаться на несовместимость типов между sum и ptr и на невозможность произвести инкремент ptr, поскольку это массив вообще-то.
Записан

Страниц: [1]   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!