Помощь - Поиск - Пользователи - Календарь
Полная версия: md5
Форум «Всё о Паскале» > Delphi, Assembler и другие языки. > Другие языки
willhunting
Пытаюсь запустить хэш-функцию( md5).
код взял на каком-то сайте

md5.cpp

#include "md5.h"

BYTE m_lpszBuffer[64];
ULONG m_nCount[2];
ULONG m_lMD5[4];

static unsigned char PADDING[64] = {
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))

#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))

#define FF(a, b, c, d, x, s, ac) \
{(a) += F ((b), ©, (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) \
{(a) += G ((b), ©, (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) \
{(a) += H ((b), ©, (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) \
{(a) += I ((b), ©, (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}

void ByteToDWord(DWORD* Output, ULONG* Input, UINT nLength){
UINT i=0;
UINT j=0;
for (; j < nLength; i++, j += 4)
{
Output[i] = (ULONG)Input[j] |
(ULONG)Input[j+1] << 8 |
(ULONG)Input[j+2] << 16 |
(ULONG)Input[j+3] << 24;
}
}

void DWordToByte(unsigned char* Output, DWORD* Input, UINT nLength ){
UINT i = 0;
UINT j = 0;
for (; j < nLength; i++, j += 4)
{
Output[j] = (UCHAR)(Input[i] & 0xff);
Output[j+1] = (UCHAR)((Input[i] >> 8) & 0xff);
Output[j+2] = (UCHAR)((Input[i] >> 16) & 0xff);
Output[j+3] = (UCHAR)((Input[i] >> 24) & 0xff);
}
}

void MD5Init (void)
{
memset(m_lpszBuffer, 0, 64 );
m_nCount[0] = m_nCount[1] = 0;

m_lMD5[0] = MD5_INIT_STATE_0;
m_lMD5[1] = MD5_INIT_STATE_1;
m_lMD5[2] = MD5_INIT_STATE_2;
m_lMD5[3] = MD5_INIT_STATE_3;
}

void MD5Update (unsigned char *inBuf, unsigned int inLen)
{
register int i, ii;
int mdi;
UINT4 in[16];

mdi = (int)((m_nCount[0] >> 3) & 0x3F);

if ((m_nCount[0] + ((UINT4)inLen << 3)) < m_nCount[0])
m_nCount[1]++;
m_nCount[0] += ((UINT4)inLen << 3);
m_nCount[1] += ((UINT4)inLen >> 29);

while (inLen--) {
m_lpszBuffer[mdi++] = *inBuf++;

if (mdi == 0x40) {
for (i = 0, ii = 0; i < 16; i++, ii += 4)
in[i] = (((UINT4)m_lpszBuffer[ii+3]) << 24) |
(((UINT4)m_lpszBuffer[ii+2]) << 16) |
(((UINT4)m_lpszBuffer[ii+1]) << 8) |
((UINT4)m_lpszBuffer[ii]);
Transform (m_lMD5, in);
mdi = 0;
}
}
}

void MD5Final (char* cReturnStr)
{
unsigned char bits[8];
int nIndex;
unsigned int nPadLen;
const int nMD5Size = 16;
unsigned char lpszMD5[16];
char temp[2];
int i;

cReturnStr[0]='\0';

DWordToByte( bits, m_nCount, 8 );

nIndex = (int)((m_nCount[0] >> 3) & 0x3f);
nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex);
MD5Update (PADDING, nPadLen);

MD5Update (bits, 8);

DWordToByte( lpszMD5, m_lMD5, nMD5Size );

for (i=0; i < nMD5Size; i++)
{

if (lpszMD5[i] == 0) {
temp[0] = '0';
temp[1]='0';
}
else if (lpszMD5[i] <= 15) {
sprintf(temp,"0%x",lpszMD5[i]);
}
else {
sprintf(temp,"%x",lpszMD5[i]);
}
strcat(cReturnStr,temp);
}
lpszMD5[0]='\0';
}

void Transform(register UINT4 *buf,register UINT4 *in)
{
register UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];

#define S11 7
#define S12 12
#define S13 17
#define S14 22
FF ( a, b, c, d, in[ 0], S11, 0xD76AA478L);
FF ( d, a, b, c, in[ 1], S12, 0xE8C7B756L);
FF ( c, d, a, b, in[ 2], S13, 0x242070DBL);
FF ( b, c, d, a, in[ 3], S14, 0xC1BDCEEEL);
FF ( a, b, c, d, in[ 4], S11, 0xF57C0FAFL);
FF ( d, a, b, c, in[ 5], S12, 0x4787C62AL);
FF ( c, d, a, b, in[ 6], S13, 0xA8304613L);
FF ( b, c, d, a, in[ 7], S14, 0xFD469501L);
FF ( a, b, c, d, in[ 8], S11, 0x698098D8L);
FF ( d, a, b, c, in[ 9], S12, 0x8B44F7AFL);
FF ( c, d, a, b, in[10], S13, 0xFFFF5BB1L);
FF ( b, c, d, a, in[11], S14, 0x895CD7BEL);
FF ( a, b, c, d, in[12], S11, 0x6B901122L);
FF ( d, a, b, c, in[13], S12, 0xFD987193L);
FF ( c, d, a, b, in[14], S13, 0xA679438EL);
FF ( b, c, d, a, in[15], S14, 0x49B40821L);

#define S21 5
#define S22 9
#define S23 14
#define S24 20
GG ( a, b, c, d, in[ 1], S21, 0xF61E2562L);
GG ( d, a, b, c, in[ 6], S22, 0xC040B340L);
GG ( c, d, a, b, in[11], S23, 0x265E5A51L);
GG ( b, c, d, a, in[ 0], S24, 0xE9B6C7AAL);
GG ( a, b, c, d, in[ 5], S21, 0xD62F105DL);
GG ( d, a, b, c, in[10], S22, 0x02441453L);
GG ( c, d, a, b, in[15], S23, 0xD8A1E681L);
GG ( b, c, d, a, in[ 4], S24, 0xE7D3FBC8L);
GG ( a, b, c, d, in[ 9], S21, 0x21E1CDE6L);
GG ( d, a, b, c, in[14], S22, 0xC33707D6L);
GG ( c, d, a, b, in[ 3], S23, 0xF4D50D87L);
GG ( b, c, d, a, in[ 8], S24, 0x455A14EDL);
GG ( a, b, c, d, in[13], S21, 0xA9E3E905L);
GG ( d, a, b, c, in[ 2], S22, 0xFCEFA3F8L);
GG ( c, d, a, b, in[ 7], S23, 0x676F02D9L);
GG ( b, c, d, a, in[12], S24, 0x8D2A4C8AL);

#define S31 4
#define S32 11
#define S33 16
#define S34 23
HH ( a, b, c, d, in[ 5], S31, 0xFFFA3942L);
HH ( d, a, b, c, in[ 8], S32, 0x8771F681L);
HH ( c, d, a, b, in[11], S33, 0x6D9D6122L);
HH ( b, c, d, a, in[14], S34, 0xFDE5380CL);
HH ( a, b, c, d, in[ 1], S31, 0xA4BEEA44L);
HH ( d, a, b, c, in[ 4], S32, 0x4BDECFA9L);
HH ( c, d, a, b, in[ 7], S33, 0xF6BB4B60L);
HH ( b, c, d, a, in[10], S34, 0xBEBFBC70L);
HH ( a, b, c, d, in[13], S31, 0x289B7EC6L);
HH ( d, a, b, c, in[ 0], S32, 0xEAA127FAL);
HH ( c, d, a, b, in[ 3], S33, 0xD4EF3085L);
HH ( b, c, d, a, in[ 6], S34, 0x04881D05L);
HH ( a, b, c, d, in[ 9], S31, 0xD9D4D039L);
HH ( d, a, b, c, in[12], S32, 0xE6DB99E5L);
HH ( c, d, a, b, in[15], S33, 0x1FA27CF8L);
HH ( b, c, d, a, in[ 2], S34, 0xC4AC5665L);

#define S41 6
#define S42 10
#define S43 15
#define S44 21
II ( a, b, c, d, in[ 0], S41, 0xF4292244L);
II ( d, a, b, c, in[ 7], S42, 0x432AFF97L);
II ( c, d, a, b, in[14], S43, 0xAB9423A7L);
II ( b, c, d, a, in[ 5], S44, 0xFC93A039L);
II ( a, b, c, d, in[12], S41, 0x655B59C3L);
II ( d, a, b, c, in[ 3], S42, 0x8F0CCC92L);
II ( c, d, a, b, in[10], S43, 0xFFEFF47DL);
II ( b, c, d, a, in[ 1], S44, 0x85845DD1L);
II ( a, b, c, d, in[ 8], S41, 0x6FA87E4FL);
II ( d, a, b, c, in[15], S42, 0xFE2CE6E0L);
II ( c, d, a, b, in[ 6], S43, 0xA3014314L);
II ( b, c, d, a, in[13], S44, 0x4E0811A1L);
II ( a, b, c, d, in[ 4], S41, 0xF7537E82L);
II ( d, a, b, c, in[11], S42, 0xBD3AF235L);
II ( c, d, a, b, in[ 2], S43, 0x2AD7D2BBL);
II ( b, c, d, a, in[ 9], S44, 0xEB86D391L);

buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}

void GetMD5(char* pBuf, UINT nLength,char* cReturnStr) {
MD5Init();
MD5Update(pBuf, nLength);
MD5Final(cReturnStr);
}

AnsiString MD5(AnsiString in) {
char out_char[32];
GetMD5(in.c_str(),in.Length(),out_char);
return AnsiString(out_char);
}





md5.h

#include <system.hpp>
#include <windef.h>
#include <stdio.h>


#ifdef __alpha
typedef unsigned int UINT4;
#else
typedef unsigned long int UINT4;
#endif

#define MD5_INIT_STATE_0 0x67452301
#define MD5_INIT_STATE_1 0xefcdab89
#define MD5_INIT_STATE_2 0x98badcfe
#define MD5_INIT_STATE_3 0x10325476

void MD5Init(void);
void MD5Update(unsigned char *bug, unsigned int len);
void MD5Final(char* cReturnStr);
void Transform(UINT4 *buf, UINT4 *in);
void GetMD5(char* pBuf, UINT nLength,char* cReturnStr);
AnsiString MD5(AnsiString in);




Вылетает fatal error C1083: Cannot open include file: 'system.hpp': No such file or directory
Error executing cl.exe.


среда VC++6
создал проект Win32 App на VC++ 6.0 . И вставил файлы md5.cpp,md5.h
volvo
Судя по
AnsiString MD5(AnsiString in);
, код ни разу не для VC, а для Билдера... Кстати, это вообще не С++, это чистый С, поэтому расширение файла желательно сделать md5.c, а не md5.cpp
willhunting
А, да это действительно builder, спасибо. Только здесь можно вычислять md5 от строки. А что надо изменить, что бы вычислять md5 от файла ?
volvo
Считай весь файл в строку и вычисли ее MD5...
willhunting
Цитата(volvo @ 3.02.2010 18:35) *

Считай весь файл в строку и вычисли ее MD5...

Как сделать строку из файла произвольного формата ? Т.е. например из файлов mpeg, jpeg или какой-нибудь базы данных(архивируя или не архивируя) ? И какая длина строки получиться при этом ?

Я тут пробовал открыть видео файл блокнотом smile.gif Этот набор символов не является ли строкой ? smile.gif


volvo
А, так тебе для бинарного файла: Вот так, например:

#define BUFSIZE 32768

/* ... */
MD5Init();
int k = open("file.avi", O_BINARY | O_RDONLY);
if( k == -1 )
{
return;
}

int was_read;
unsigned char *buffer = new unsigned char[BUFSIZE];

while( (was_read = read(k, buffer, BUFSIZE)) > 0 )
{
MD5Update(buffer, was_read);
}

close(k);
MD5Final((char*)buffer);
printf("MD5 = %s\n", buffer);
delete[] buffer;
/* ... */
willhunting
Т.е. нужно вместо этого
AnsiString MD5(AnsiString in) {
char out_char[32];
GetMD5(in.c_str(),in.Length(),out_char);
return AnsiString(out_char);
}


ставить это

MD5Init();
int k = open("file.avi", O_BINARY | O_RDONLY);
if( k == -1 )
{
return;
}

int was_read;
unsigned char *buffer = new unsigned char[BUFSIZE];

while( (was_read = read(k, buffer, BUFSIZE)) > 0 )
{
MD5Update(buffer, was_read);
}

close(k);
MD5Final((char*)buffer);
printf("MD5 = %s\n", buffer);
delete[] buffer;


?

или после MD5Init(); ?

А нет судя по
 printf("MD5 = %s\n", buffer);
это для с.
volvo
То, что я привел - надо написать в основной программе. У тебя здесь основной программы нет, только сама библиотека... Где main() ? Как ты сумел найти MD5 от AnsiString-а? Вот туда вместо тех вызовов, что у тебя, поставь мой код...

Цитата
это для с.
Блин... Да, это я, как всегда, глючу... Я С не использую, только С++... Ну, тогда замени
unsigned char *buffer = new unsigned  char[BUFSIZE];
на
unsigned char *buffer = (unsigned char *)malloc(BUFSIZE * sizeof(unsigned char));
, и для удаления - не delete, а free...
willhunting
было
//---------------------------------------------------------------------------

#include <vcl.h>
#include "md5.h"
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
Edit2->Text=MD5(Edit1->Text);
}
//------


стало
//---------------------------------------------------------------------------

#include <vcl.h>
#include "md5.h"
#pragma hdrstop

#define BUFSIZE 32768
#include <fcntl.h>
#include <sys\stat.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
MD5Init();
int k = open("c:\\avi.mp4", O_BINARY | O_RDONLY);
if( k == -1 )
{
return;
}

int was_read;

unsigned char *buffer = (unsigned char *)malloc(BUFSIZE * sizeof(unsigned char));

while( (was_read = read(k, buffer, BUFSIZE)) > 0 )
{
MD5Update(buffer, was_read);
}

close(k);
MD5Final((char*)buffer);
printf("MD5 = %s\n", buffer);
delete[] buffer;


Edit2->Text=buffer;
delete[] buffer;
}
//--------------------------


поменял
Edit2->Text=buffer;


ругается

[C++ Error] Unit1.cpp(54): E2034 Cannot convert 'unsigned char *' to 'AnsiString'

на free
[C++ Error] Unit1.cpp(51): E2188 Expression syntax
volvo
Ну, а я сделал так:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include <fcntl.h>
#include <io.h>

#include "md5.h"
#include "Unit1.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
#define BUFSIZE 0x8000
void __fastcall TForm1::Button1Click(TObject *Sender)
{
MD5Init();
int k = open("F:\\Programs\\DRKB3_Full.chm", O_BINARY | O_RDONLY);
if( k == -1 )
{
return;
}
int was_read;
unsigned char *buffer = new unsigned char[BUFSIZE];
while( (was_read = read(k, buffer, BUFSIZE)) > 0 )
{
MD5Update(buffer, was_read);
}
close(k);
MD5Final((char*)buffer);

AnsiString s;
s.printf("%s", buffer);
Edit1->Text = s;
delete[] buffer;
}
//---------------------------------------------------------------------------

, и работает... Что я делаю не так?
willhunting
volvo, просто огромное спасибо тебе !
зы ура заработало smile.gif
willhunting
так...
интересно, а можно выгружать содержательную информацию(не учитывать служебную информацию) из базы данных и брать хэш от неё ? это может ускорить процесс .
теперь главный вопрос: как можно выгрузить информацию из бд ?
volvo
Цитата
интересно, а можно выгружать содержательную информацию(не учитывать служебную информацию) из базы данных и брать хэш от неё ?
Интересно, а как мы должны знать, можно это или нет, если ты не сказал, что за база у тебя, что за содержательная информация, от которой надо брать хеш? Как она хранится?
willhunting
Цитата(volvo @ 20.02.2010 0:29) *

Интересно, а как мы должны знать, можно это или нет, если ты не сказал, что за база у тебя, что за содержательная информация, от которой надо брать хеш? Как она хранится?

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

volvo
Цитата
мне не важно какая конкретно база, а важно возможно ли это использовать
Неважно, говоришь? Ты сам сказал, учти smile.gif

База MS Access, подключение через ADO, получаем содержимое информационного поля типа MEMO в строку:
String s = DataSource1->DataSet->FieldByName("info")->AsString;

и находим хеш этой строки. Ты уже умеешь это делать...

Ну, что, помогло тебе это? А как ты будешь действовать, если у тебя не поле MEMO, а OLEObject хранит данные? Я ж ничего просто так не спрашиваю... "Общая температура по больнице" - это никому не нужная информация. Для общего случая НИКОГДА и НИЧЕГО не делается... Всегда рассматриваются какие-то конкретные вещи.
willhunting
Если рассмотреть простейший пример БД access если в ней хранится только текстовая информация. Т.е. формат всех полей либо “буквы” либо “цифры”. Таким образом , нужно пробежаться по всем таблицам и всем ячейкам этих таблиц. Так ведь возможно сделать ?

willhunting


Я правильно понимаю, что параллельное программирование сюда никак не применить ?
volvo
Что имеешь в виду под "параллельным программированием"? Многопоточное приложение (каждый поток читает, скажем, свою таблицу, или свою часть таблицы, если сама база банных разрешает такой доступ) не устроит? На многоядерной/многопроцессорной машине будет выполняться параллельно. По крайней мере, если число потоков соизмеримо с количеством ядер/процессоров.
willhunting
Цитата(volvo @ 12.03.2010 22:26) *

Что имеешь в виду под "параллельным программированием"? Многопоточное приложение (каждый поток читает, скажем, свою таблицу, или свою часть таблицы, если сама база банных разрешает такой доступ) не устроит? На многоядерной/многопроцессорной машине будет выполняться параллельно. По крайней мере, если число потоков соизмеримо с количеством ядер/процессоров.

я хэш-функцию имел ввиду(распараллелить её вычисление)
volvo
Цитата
я хэш-функцию имел ввиду(распараллелить её вычисление)
Нет, нельзя, тут нет независимых вычислений, поэтому подсчет должен быть последовательным. Но по-моему, ты копаешь не в ту сторону. Зачем тебе понадобилось распараллеливать вычисление каждого хеша, если можно сделать параллельное вычисление нескольких хешей безо всяких проблем?
willhunting
Цитата(volvo @ 13.03.2010 12:03) *

Нет, нельзя, тут нет независимых вычислений, поэтому подсчет должен быть последовательным. Но по-моему, ты копаешь не в ту сторону. Зачем тебе понадобилось распараллеливать вычисление каждого хеша, если можно сделать параллельное вычисление нескольких хешей безо всяких проблем?

Что значит нескольких хэшей ? На выходе мы же должны получить один хэш.
volvo
Блин... Тебя не поймешь. Ты задачу поставь толком, чтоб знать, чего тебе ТЕПЕРЬ нужно... А то крутишься вокруг и около - "мне в общем, знать бы, такое вообще возможно или нет". ЧЕГО возможно или нет? Сам спрашивал, можно ли иметь доступ к части базы данных, чтоб взять от нее хеш? Можно. Зачем оно тебе было надо, спрашивается? Чтобы тут же считать общий хеш для всей базы? Так зачем спрашивал о хеше частичном?

В общем, опять Сага об X, Y, Z. Надоело. Нет четкой постановки задачи - нет больше ответов. Задачу типа "Иди туда, не знаю куда, принеси то, не знаю что" (С) решают в сказках. Туда и обращайся...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.