Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> работающая функция md5 
:(
    Опции темы
kirufka
Дата 30.10.2008, 18:15 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 2.10.2008
Где: Москва

Репутация: нет
Всего: нет



Народ.. Ну вот сколько читал, так и не понял как сделать! у меня конечно руки наверно корявые, но можете пжл написать алгоритм вычисления md5 строки и обьяснить его (тк алгоритмов видел много, но с объяснением и понятным кодом ещё не видел)
 smile  smile 
PM MAIL Jabber   Вверх
bsa
Дата 30.10.2008, 19:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



md5.hpp:
Код
#ifndef MD5_HPP_
# define MD5_HPP_
/* rfc1321 */

//-----------------------------------------------------------------------------
/** \brief C++ реализация подсчета хэша методом MD5
 */
class HashMD5
{
    /// \brief состояние подсчета (числа A, B, C и D)
    union State {
        unsigned data[4];
        struct {
            unsigned A, B, C, D;
        };
        /// \brief шаблон вместо определения в исходной реализации на Си
        template<class T>
        inline void Process(unsigned &a, unsigned b, unsigned c, unsigned d, unsigned k, unsigned s, unsigned t, const T &func) {
            a += func(b,c,d) + k + t;
            a = ((a << s) | (a >> (32 - s))) + b;
        }
        /// \brief функция, используемая на первом раунде рассчета
        struct Round1 {
            unsigned operator()(unsigned x, unsigned y, unsigned z) const {
                return z ^ (x & (y ^ z));
            }
        };
        /// \brief функция, используемая на втором раунде рассчета
        struct Round2 {
            unsigned operator()(unsigned x, unsigned y, unsigned z) const {
                return y ^ (z & (x ^ y));
            }
        };
        /// \brief функция, используемая на третьем раунде рассчета
        struct Round3 {
            unsigned operator()(unsigned x, unsigned y, unsigned z) const {
                return x ^ y ^ z;
            }
        };
        /// \brief функция, используемая на четвертом раунде рассчета
        struct Round4 {
            unsigned operator()(unsigned x, unsigned y, unsigned z) const {
                return y ^ (x | (~z));
            }
        };

    public:
        enum {
            DigestSize = 16        ///< количество байт в хэше
        };

        /// \brief конструктор
        State() { reset(); }

        /// \brief обновляет состояние блоком из 64 байт
        void update(const unsigned *buffer);

        /// \brief возвращает текущее состояние
        const void* getDigest() const { return data; }

        /// \brief сброс в исходное состояние
        void reset() {
            A = 0x67452301U;
            B = 0xefcdab89U;
            C = 0x98badcfeU;
            D = 0x10325476U;
        }
    };

    State state;                    ///< состояние
    unsigned long long bits_count;    ///< количество обсчитанных бит
    unsigned char *buffer;            ///< содержит данные перед обсчетом
    unsigned char *hash;            ///< временный буфер хэша, уничтожаемый методом update()

    unsigned get_bytes_in_buffer() const {
        return (bits_count >> 3) & 0x3F;
    }

    void create_hash();
    void destroy_hash() {
        delete []hash;
        hash = 0;
    }
protected:
public:
    enum {
        DigestSize = State::DigestSize    ///< количество байт в хэше
    };

    /// \brief конструктор
    HashMD5() : hash(0) {
        buffer = new unsigned char[64];
        reset();
    }
    /// \brief деструктор
    ~HashMD5() {
        delete []hash;
        delete []buffer;
    }
    /** \brief сброс состояния в исходное
     *
     * После сброса состояния рассчет хеша начинается заного
     */
    void reset(void) {
        bits_count = 0;
        state.reset();
        destroy_hash();
    }

    /** \brief обновление состояния
     * @param buffer указатель на массив данных
     * @param size размер массива данных
     */
    void update(const void *buffer, size_t size);

    /** \brief рассчет конечного значения хеша и возврат его пользователю
     * @param buffer буфер, в который нужно поместить полученный хэш
     * @return buffer, если он не был равен 0, или указатель на внутренний буфер, который будет уничтожен последующим вызовом update()
     * @note данной функцией можно пользоваться для получения промежуточного хеша
     */
    const void* get(void *buffer = 0) {
        if ( !hash )
            create_hash();
        if (buffer)
            std::memcpy(buffer, hash, DigestSize);
        else
            buffer = hash;
        return buffer;
    }
};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#endif // MD5_HPP_
//-----------------------------------------------------------------------------
md5.cpp:
Код
#include <cstring>
#include "md5.hpp"

//-----------------------------------------------------------------------------
void HashMD5::State::update(const unsigned *data)
{
    unsigned A = this->A;
    unsigned B = this->B;
    unsigned C = this->C;
    unsigned D = this->D;

    Process( A, B, C, D, data[ 0],  7, 0xD76AA478, Round1() );
    Process( D, A, B, C, data[ 1], 12, 0xE8C7B756, Round1() );
    Process( C, D, A, B, data[ 2], 17, 0x242070DB, Round1() );
    Process( B, C, D, A, data[ 3], 22, 0xC1BDCEEE, Round1() );
    Process( A, B, C, D, data[ 4],  7, 0xF57C0FAF, Round1() );
    Process( D, A, B, C, data[ 5], 12, 0x4787C62A, Round1() );
    Process( C, D, A, B, data[ 6], 17, 0xA8304613, Round1() );
    Process( B, C, D, A, data[ 7], 22, 0xFD469501, Round1() );
    Process( A, B, C, D, data[ 8],  7, 0x698098D8, Round1() );
    Process( D, A, B, C, data[ 9], 12, 0x8B44F7AF, Round1() );
    Process( C, D, A, B, data[10], 17, 0xFFFF5BB1, Round1() );
    Process( B, C, D, A, data[11], 22, 0x895CD7BE, Round1() );
    Process( A, B, C, D, data[12],  7, 0x6B901122, Round1() );
    Process( D, A, B, C, data[13], 12, 0xFD987193, Round1() );
    Process( C, D, A, B, data[14], 17, 0xA679438E, Round1() );
    Process( B, C, D, A, data[15], 22, 0x49B40821, Round1() );

    Process( A, B, C, D, data[ 1],  5, 0xF61E2562, Round2() );
    Process( D, A, B, C, data[ 6],  9, 0xC040B340, Round2() );
    Process( C, D, A, B, data[11], 14, 0x265E5A51, Round2() );
    Process( B, C, D, A, data[ 0], 20, 0xE9B6C7AA, Round2() );
    Process( A, B, C, D, data[ 5],  5, 0xD62F105D, Round2() );
    Process( D, A, B, C, data[10],  9, 0x02441453, Round2() );
    Process( C, D, A, B, data[15], 14, 0xD8A1E681, Round2() );
    Process( B, C, D, A, data[ 4], 20, 0xE7D3FBC8, Round2() );
    Process( A, B, C, D, data[ 9],  5, 0x21E1CDE6, Round2() );
    Process( D, A, B, C, data[14],  9, 0xC33707D6, Round2() );
    Process( C, D, A, B, data[ 3], 14, 0xF4D50D87, Round2() );
    Process( B, C, D, A, data[ 8], 20, 0x455A14ED, Round2() );
    Process( A, B, C, D, data[13],  5, 0xA9E3E905, Round2() );
    Process( D, A, B, C, data[ 2],  9, 0xFCEFA3F8, Round2() );
    Process( C, D, A, B, data[ 7], 14, 0x676F02D9, Round2() );
    Process( B, C, D, A, data[12], 20, 0x8D2A4C8A, Round2() );

    Process( A, B, C, D, data[ 5],  4, 0xFFFA3942, Round3() );
    Process( D, A, B, C, data[ 8], 11, 0x8771F681, Round3() );
    Process( C, D, A, B, data[11], 16, 0x6D9D6122, Round3() );
    Process( B, C, D, A, data[14], 23, 0xFDE5380C, Round3() );
    Process( A, B, C, D, data[ 1],  4, 0xA4BEEA44, Round3() );
    Process( D, A, B, C, data[ 4], 11, 0x4BDECFA9, Round3() );
    Process( C, D, A, B, data[ 7], 16, 0xF6BB4B60, Round3() );
    Process( B, C, D, A, data[10], 23, 0xBEBFBC70, Round3() );
    Process( A, B, C, D, data[13],  4, 0x289B7EC6, Round3() );
    Process( D, A, B, C, data[ 0], 11, 0xEAA127FA, Round3() );
    Process( C, D, A, B, data[ 3], 16, 0xD4EF3085, Round3() );
    Process( B, C, D, A, data[ 6], 23, 0x04881D05, Round3() );
    Process( A, B, C, D, data[ 9],  4, 0xD9D4D039, Round3() );
    Process( D, A, B, C, data[12], 11, 0xE6DB99E5, Round3() );
    Process( C, D, A, B, data[15], 16, 0x1FA27CF8, Round3() );
    Process( B, C, D, A, data[ 2], 23, 0xC4AC5665, Round3() );

    Process( A, B, C, D, data[ 0],  6, 0xF4292244, Round4() );
    Process( D, A, B, C, data[ 7], 10, 0x432AFF97, Round4() );
    Process( C, D, A, B, data[14], 15, 0xAB9423A7, Round4() );
    Process( B, C, D, A, data[ 5], 21, 0xFC93A039, Round4() );
    Process( A, B, C, D, data[12],  6, 0x655B59C3, Round4() );
    Process( D, A, B, C, data[ 3], 10, 0x8F0CCC92, Round4() );
    Process( C, D, A, B, data[10], 15, 0xFFEFF47D, Round4() );
    Process( B, C, D, A, data[ 1], 21, 0x85845DD1, Round4() );
    Process( A, B, C, D, data[ 8],  6, 0x6FA87E4F, Round4() );
    Process( D, A, B, C, data[15], 10, 0xFE2CE6E0, Round4() );
    Process( C, D, A, B, data[ 6], 15, 0xA3014314, Round4() );
    Process( B, C, D, A, data[13], 21, 0x4E0811A1, Round4() );
    Process( A, B, C, D, data[ 4],  6, 0xF7537E82, Round4() );
    Process( D, A, B, C, data[11], 10, 0xBD3AF235, Round4() );
    Process( C, D, A, B, data[ 2], 15, 0x2AD7D2BB, Round4() );
    Process( B, C, D, A, data[ 9], 21, 0xEB86D391, Round4() );

    this->A += A;
    this->B += B;
    this->C += C;
    this->D += D;
}
//-----------------------------------------------------------------------------
void HashMD5::update(const void *data, size_t size)
{
    destroy_hash();
    while(size) {
        size_t count = 64 - get_bytes_in_buffer();
        if (count > size)
            count = size;
        std::memcpy(buffer + get_bytes_in_buffer(), data, count);

        bits_count += (count << 3);
        data = reinterpret_cast<const char*>(data) + count;
        size -= count;

        if ( !get_bytes_in_buffer() )    //буфер полон
            state.update( reinterpret_cast<const unsigned*>(buffer) );
    }
}
//-----------------------------------------------------------------------------
void HashMD5::create_hash()
{
    if (!hash)
        hash = new unsigned char[State::DigestSize];

    static const unsigned char padding[64] = {
        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
    const unsigned bytes_in_buffer = get_bytes_in_buffer();
    const unsigned count = ( (bytes_in_buffer < 56) ? 56 : 120 ) - bytes_in_buffer;
    unsigned char *buf = new unsigned char[bytes_in_buffer + count + 8];
    std::memcpy(buf, buffer, bytes_in_buffer);
    std::memcpy(buf + bytes_in_buffer, padding, count);
    std::memcpy(buf + bytes_in_buffer + count, &bits_count, 8);
    State final( state );
    final.update( reinterpret_cast<const unsigned*>(buf) );
    if ( (count + bytes_in_buffer + 8) > 64)
        final.update( reinterpret_cast<const unsigned*>(buf + 64) );
    std::memcpy(hash, final.getDigest(), DigestSize );
    delete []buf;
}
//-----------------------------------------------------------------------------
Пользоваться очень просто:
Код
HashMD5 hash;
...
hash.reset();
hash.update(buffer, size);
...
const char *buffer = (const char*)hash.get();
for(i = 0; i < 64; ++i)
   std::cout << std::hex << std::setw(2) << std::setfill('0') << int(buffer[i]);
std::cout << std::endl;


Это сообщение отредактировал(а) bsa - 31.10.2008, 01:46
PM   Вверх
kirufka
Дата 30.10.2008, 19:21 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 2.10.2008
Где: Москва

Репутация: нет
Всего: нет



Сначала писал ошибку мол нету файла: md5.hpp, поменя в md5.cpp строку инклуда md5.hpp на md5.h
И терь самое мощно блин((( таже фигня как и тут получилась((((
http://forum.vingrad.ru/forum/topic-234297...0%B9%D1%82.html
PM MAIL Jabber   Вверх
bsa
Дата 31.10.2008, 01:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Зачем плодишь темы?
PM   Вверх
GorbunovDiman
Дата 28.4.2010, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 3.3.2008

Репутация: нет
Всего: нет



Цитата

Пользоваться очень просто:
Код

HashMD5 hash;
...
hash.reset();
hash.update(buffer, size);
...
const char *buffer = (const char*)hash.get();
for(i = 0; i < 64; ++i)
   std::cout << std::hex << std::setw(2) << std::setfill('0') << int(buffer[i]);
std::cout << std::endl;



А можно подробнее этот момент?
     1)  что скрывается под многоточием
     2)  smile   такого плана: имеется массив char[ ] , s - это его размер. В массив может быть записанна строка (посимвольно) или могут быть записанны двоичные данные. Как определить хаш этой строки, чтобы он тоже хранился в виде строки и/или в том же представлении что и входные данные? smile 


P.S
  я так понял нужно подключать md5.cpp ?
PM MAIL   Вверх
bsa
Дата 28.4.2010, 19:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



1) все что угодно - какой-то твой код, не имеющий отношения к хэшу
2) buffer в 4-й строке это именно массив типа char[], size - количество данных. Данные могут быть любые.
в строках 7-8 хэш выводится в шестнадцатиричном виде. анализируй код.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0497 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.