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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> аналог md5 функции в PHP 
:(
    Опции темы
Vaulter
Дата 23.8.2003, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



пишу:
Код

LPSTR gnr::md5(LPSTR str)
{
DWORD encl=lstrlen(str);
HCRYPTPROV csp;
if(!CryptAcquireContext(&csp,NULL,MS_DEF_PROV ,PROV_RSA_FULL,0))
 gnr::Error("CryptAcquireContext");
//gen key
HCRYPTKEY hkey;
if(!CryptGenKey(csp,CALG_MD5,0,&hkey))
 gnr::Error("Gen Key");
//crypting
if(!CryptEncrypt(hkey,0,1,0,(PBYTE)str,&encl,encl))
 gnr::Error("Encrypting");
return str;
}

выдает ошибку при генерации ключа: алгоритм не держится данным CSP....так ведь неправда ведь!!! по MSDN!
у чем дело?


--------------------
PM MAIL WWW ICQ   Вверх
Unregistered
Дата 28.8.2003, 15:39 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











ага, нашел:
md5.cpp
Код

#include "stdafx.h"



#ifdef BIG_ENDIAN_CPU
#define WORDS_BIG_ENDIAN
#endif

///#ifdef WORDS_BIG_ENDIAN
#define SWAP(n)                     \
       (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
//#else
//#define SWAP(n)                     (n)
//#endif





/* This array contains the bytes used to pad the buffer to the next
  64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
static unsigned char fillbuf[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
};







/* Initialize structure containing state of computation.
  (RFC 1321, 3.3: Step 3)  */
void            md5_init_ctx(struct md5_ctx * ctx)
{

   ctx->A = 0x67452301;
   ctx->B = 0xefcdab89;
   ctx->C = 0x98badcfe;
   ctx->D = 0x10325476;

   ctx->total[0] = ctx->total[1] = 0;
   ctx->buflen = 0;

}



/* Put result from CTX in first 16 bytes following RESBUF.  The result
  must be in little endian byte order.

  IMPORTANT: On some systems it is required that RESBUF is correctly
  aligned for a 32 bits value.  */
void           *md5_read_ctx(const struct md5_ctx * ctx, void *resbuf)
{

   ((md5_uint32 *) resbuf)[0] = SWAP(ctx->A);
   ((md5_uint32 *) resbuf)[1] = SWAP(ctx->B);
   ((md5_uint32 *) resbuf)[2] = SWAP(ctx->C);
   ((md5_uint32 *) resbuf)[3] = SWAP(ctx->D);

   return resbuf;

}




/* Process the remaining bytes in the internal buffer and the usual
  prolog according to the standard and write the result to RESBUF.

  IMPORTANT: On some systems it is required that RESBUF is correctly
  aligned for a 32 bits value.  */
void           *md5_finish_ctx(struct md5_ctx * ctx, void *resbuf)
{
   /* Take yet unprocessed bytes into account.  */
   md5_uint32      bytes = ctx->buflen;
   size_t          pad;

   /* Now count remaining bytes.  */
   ctx->total[0] += bytes;
   if (ctx->total[0] < bytes)
       ++ctx->total[1];

   pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
   memcpy(&ctx->buffer[bytes], fillbuf, pad);

   /* Put the 64-bit file length in *bits* at the end of the buffer.  */
   *(md5_uint32 *) & ctx->buffer[bytes + pad] = SWAP(ctx->total[0] << 3);
   *(md5_uint32 *) & ctx->buffer[bytes + pad + 4] = SWAP((ctx->total[1] << 3) |
                                                         (ctx->total[0] >> 29));

   /* Process last bytes.  */
   md5_process_block(ctx->buffer, bytes + pad + 8, ctx);

   return md5_read_ctx(ctx, resbuf);

}





/* Compute MD5 message digest for bytes read from STREAM.  The
  resulting message digest number will be written into the 16 bytes
  beginning at RESBLOCK.  */
int             md5_stream(FILE * stream, void *resblock)
{
   /* Important: BLOCKSIZE must be a multiple of 64.  */
#define BLOCKSIZE 4096
   struct md5_ctx  ctx;
   char            buffer[BLOCKSIZE + 72];
   size_t          sum;

   /* Initialize the computation context.  */
   md5_init_ctx(&ctx);

   /* Iterate over full file contents.  */
   while (1)
   {
       /* We read the file in blocks of BLOCKSIZE bytes.  One call of the computation
          function processes the whole buffer so that with the next round of the loop
          another block can be read.  */
       size_t          n;
       sum = 0;

       /* Read block.  Take care for partial reads.  */
       do
       {
           n = fread(buffer + sum, 1, BLOCKSIZE - sum, stream);

           sum += n;
       }
       while (sum < BLOCKSIZE && n != 0);
       if (n == 0 && ferror(stream))
           return 1;

       /* If end of file is reached, end the loop.  */
       if (n == 0)
           break;

       /* Process buffer with BLOCKSIZE bytes.  Note that BLOCKSIZE % 64 == 0 */
       md5_process_block(buffer, BLOCKSIZE, &ctx);
   }

   /* Add the last bytes if necessary.  */
   if (sum > 0)
       md5_process_bytes(buffer, sum, &ctx);

   /* Construct result in desired memory.  */
   md5_finish_ctx(&ctx, resblock);

   return 0;

}





/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
  result is always in little endian byte order, so that a byte-wise
  output yields to the wanted ASCII representation of the message
  digest.  */
void           *md5_buffer(const char *buffer, size_t len, void *resblock)
{

   struct md5_ctx  ctx;

   /* Initialize the computation context.  */
   md5_init_ctx(&ctx);

   /* Process whole buffer but last len % 64 bytes.  */
   md5_process_bytes(buffer, len, &ctx);

   /* Put result in desired memory area.  */
   return md5_finish_ctx(&ctx, resblock);

}






void            md5_process_bytes(const void *buffer, size_t len, struct md5_ctx * ctx)
{
   /* When we already have some bits in our internal buffer concatenate both
      inputs first.  */
   if (ctx->buflen != 0)
   {
       size_t          left_over = ctx->buflen;
       size_t          add = 128 - left_over > len ? len : 128 - left_over;

       memcpy(&ctx->buffer[left_over], buffer, add);
       ctx->buflen += add;

       if (left_over + add > 64)
       {
           md5_process_block(ctx->buffer, (left_over + add) & ~63, ctx);
           /* The regions in the following copy operation cannot overlap.  */
           memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
                  (left_over + add) & 63);
           ctx->buflen = (left_over + add) & 63;
       }

       buffer = (const char *) buffer + add;
       len -= add;
   }

   /* Process available complete blocks.  */
   if (len > 64)
   {
       md5_process_block(buffer, len & ~63, ctx);
       buffer = (const char *) buffer + (len & ~63);
       len &= 63;
   }

   /* Move remaining bytes in internal buffer.  */
   if (len > 0)
   {
       memcpy(ctx->buffer, buffer, len);
       ctx->buflen = len;
   }

}






/* These are the four functions used in the four steps of the MD5 algorithm
  and defined in the RFC 1321.  The first function is a little bit optimized
  (as found in Colin Plumbs public domain implementation).  */
/* #define FF(b, c, d) ((b & c) | (~b & d)) */
#define FF(b, c, d)             (d ^ (b & (c ^ d)))
#define FG(b, c, d)             FF(d, b, c)
#define FH(b, c, d)             (b ^ c ^ d)
#define FI(b, c, d)             (c ^ (b | ~d))



/* Process LEN bytes of BUFFER, accumulating context into CTX.
  It is assumed that LEN % 64 == 0.  */

void            md5_process_block(const void *buffer, size_t len, struct md5_ctx * ctx)
{

   md5_uint32      correct_words[16];
   const md5_uint32 *words = (const md5_uint32 *) buffer;
   size_t          nwords = len / sizeof(md5_uint32);
   const md5_uint32 *endp = words + nwords;

   md5_uint32      A = ctx->A;
   md5_uint32      B = ctx->B;
   md5_uint32      C = ctx->C;
   md5_uint32      D = ctx->D;

   /* First increment the byte count.  RFC 1321 specifies the possible length of
      the file up to 2^64 bits.  Here we only compute the number of bytes.  Do a
      double word increment.  */
   ctx->total[0] += len;
   if (ctx->total[0] < len)
       ++ctx->total[1];

   /* Process all bytes in the buffer with 64 bytes in each round of the loop.  */
   while (words < endp)
   {
       md5_uint32     *cwp = correct_words;
       md5_uint32      A_save = A;
       md5_uint32      B_save = B;
       md5_uint32      C_save = C;
       md5_uint32      D_save = D;

       /* First round: using the given function, the context and a constant the next
          context is computed.  Because the algorithms processing unit is a 32-bit
          word and it is determined to work on words in little endian byte order we
          perhaps have to change the byte order before the computation.  To reduce
          the work for the next steps we store the swapped words in the array
          CORRECT_WORDS.  */

#define OP1(a, b, c, d, s, T)      \
     do        \
       {        \
  a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T;  \
  ++words;       \
  CYCLIC (a, s);      \
  a += b;       \
       }        \
     while (0)

       /* It is unfortunate that C does not provide an operator for cyclic rotation.
          Hope the C compiler is smart enough.  */
#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))

       /* Before we start, one word to the strange constants. They are defined in RFC
          1321 as

          T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 */

       /* Round 1.  */
       OP1(A, B, C, D, 7, 0xd76aa478);
       OP1(D, A, B, C, 12, 0xe8c7b756);
       OP1(C, D, A, B, 17, 0x242070db);
       OP1(B, C, D, A, 22, 0xc1bdceee);
       OP1(A, B, C, D, 7, 0xf57c0faf);
       OP1(D, A, B, C, 12, 0x4787c62a);
       OP1(C, D, A, B, 17, 0xa8304613);
       OP1(B, C, D, A, 22, 0xfd469501);
       OP1(A, B, C, D, 7, 0x698098d8);
       OP1(D, A, B, C, 12, 0x8b44f7af);
       OP1(C, D, A, B, 17, 0xffff5bb1);
       OP1(B, C, D, A, 22, 0x895cd7be);
       OP1(A, B, C, D, 7, 0x6b901122);
       OP1(D, A, B, C, 12, 0xfd987193);
       OP1(C, D, A, B, 17, 0xa679438e);
       OP1(B, C, D, A, 22, 0x49b40821);

       /* For the second to fourth round we have the possibly swapped words in
          CORRECT_WORDS.  Redefine the macro to take an additional first argument
          specifying the function to use.  */
#undef OP1
#define OP(f, a, b, c, d, k, s, T)     \
     do         \
{        \
  a += f (b, c, d) + correct_words[k] + T;   \
  CYCLIC (a, s);      \
  a += b;       \
}        \
     while (0)

       /* Round 2.  */
       OP(FG, A, B, C, D, 1, 5, 0xf61e2562);
       OP(FG, D, A, B, C, 6, 9, 0xc040b340);
       OP(FG, C, D, A, B, 11, 14, 0x265e5a51);
       OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
       OP(FG, A, B, C, D, 5, 5, 0xd62f105d);
       OP(FG, D, A, B, C, 10, 9, 0x02441453);
       OP(FG, C, D, A, B, 15, 14, 0xd8a1e681);
       OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
       OP(FG, A, B, C, D, 9, 5, 0x21e1cde6);
       OP(FG, D, A, B, C, 14, 9, 0xc33707d6);
       OP(FG, C, D, A, B, 3, 14, 0xf4d50d87);
       OP(FG, B, C, D, A, 8, 20, 0x455a14ed);
       OP(FG, A, B, C, D, 13, 5, 0xa9e3e905);
       OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);
       OP(FG, C, D, A, B, 7, 14, 0x676f02d9);
       OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);

       /* Round 3.  */
       OP(FH, A, B, C, D, 5, 4, 0xfffa3942);
       OP(FH, D, A, B, C, 8, 11, 0x8771f681);
       OP(FH, C, D, A, B, 11, 16, 0x6d9d6122);
       OP(FH, B, C, D, A, 14, 23, 0xfde5380c);
       OP(FH, A, B, C, D, 1, 4, 0xa4beea44);
       OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9);
       OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60);
       OP(FH, B, C, D, A, 10, 23, 0xbebfbc70);
       OP(FH, A, B, C, D, 13, 4, 0x289b7ec6);
       OP(FH, D, A, B, C, 0, 11, 0xeaa127fa);
       OP(FH, C, D, A, B, 3, 16, 0xd4ef3085);
       OP(FH, B, C, D, A, 6, 23, 0x04881d05);
       OP(FH, A, B, C, D, 9, 4, 0xd9d4d039);
       OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);
       OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);
       OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);

       /* Round 4.  */
       OP(FI, A, B, C, D, 0, 6, 0xf4292244);
       OP(FI, D, A, B, C, 7, 10, 0x432aff97);
       OP(FI, C, D, A, B, 14, 15, 0xab9423a7);
       OP(FI, B, C, D, A, 5, 21, 0xfc93a039);
       OP(FI, A, B, C, D, 12, 6, 0x655b59c3);
       OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92);
       OP(FI, C, D, A, B, 10, 15, 0xffeff47d);
       OP(FI, B, C, D, A, 1, 21, 0x85845dd1);
       OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f);
       OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
       OP(FI, C, D, A, B, 6, 15, 0xa3014314);
       OP(FI, B, C, D, A, 13, 21, 0x4e0811a1);
       OP(FI, A, B, C, D, 4, 6, 0xf7537e82);
       OP(FI, D, A, B, C, 11, 10, 0xbd3af235);
       OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
       OP(FI, B, C, D, A, 9, 21, 0xeb86d391);

       /* Add the starting values of the context.  */
       A += A_save;
       B += B_save;
       C += C_save;
       D += D_save;
   }

   /* Put checksum in context given as argument.  */
   ctx->A = A;
   ctx->B = B;
   ctx->C = C;
   ctx->D = D;

}





void            md5_hex(unsigned char *src, char *dst)
{

   unsigned        i,
       c;
   static const char hex[] = "0123456789abcdef";

   for (i = 0; i < 16; i++)
   {
       c = src[i];
       dst[i * 2 + 0] = hex[c >> 4];
       dst[i * 2 + 1] = hex[c & 0x0F];
   }

   dst[32] = '\0';

}



void            do_md5_file(FILE * src, long start, long bytes, char *hash)
{

   struct md5_ctx  ctx;
   char            buff[1024];
   unsigned char   result[16];
   int             n;

   md5_init_ctx(&ctx);

   fseek(src, start, SEEK_SET);

   while (bytes > 0)
   {
       n = fread(buff, 1, Min(bytes, sizeof(buff)), src);
       if (n <= 0)
           break;
       md5_process_bytes(buff, n, &ctx);
       bytes -= n;
   }

   md5_finish_ctx(&ctx, result);
   md5_hex(result, hash);

}



void            do_md5_string(char *pass, int passlen, char *hash)
{

   struct md5_ctx  ctx;
   unsigned char   result[16];

   md5_init_ctx(&ctx);
   md5_process_bytes(pass, passlen, &ctx);
   md5_finish_ctx(&ctx, result);
   md5_hex(result, hash);

}

  Вверх
Unregistered
Дата 28.8.2003, 15:39 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











md5.h
Код

#ifndef _MD5_H
#define _MD5_H

#define Min(a, b)               (((a) < (b)) ? (a): (b))




typedef UINT32 md5_uint32;





/* Structure to save state of computation between the single steps.  */
struct md5_ctx
{
   md5_uint32      A;
   md5_uint32      B;
   md5_uint32      C;
   md5_uint32      D;

   md5_uint32      total[2];
   md5_uint32      buflen;
   char            buffer[128];
};

/*
* The following three functions are build up the low level used in
* the functions `md5_stream' and `md5_buffer'.
*/

/* Initialize structure containing state of computation.
  (RFC 1321, 3.3: Step 3)  */
extern void     md5_init_ctx(struct md5_ctx * ctx);

/* Starting with the result of former calls of this function (or the
  initialization function update the context for the next LEN bytes
  starting at BUFFER.
  It is necessary that LEN is a multiple of 64!!! */
extern void     md5_process_block(const void *buffer, size_t len,
                                 struct md5_ctx * ctx);

/* Starting with the result of former calls of this function (or the
  initialization function update the context for the next LEN bytes
  starting at BUFFER.
  It is NOT required that LEN is a multiple of 64.  */
extern void     md5_process_bytes(const void *buffer, size_t len,
                                 struct md5_ctx * ctx);

/* Process the remaining bytes in the buffer and put result from CTX
  in first 16 bytes following RESBUF.  The result is always in little
  endian byte order, so that a byte-wise output yields to the wanted
  ASCII representation of the message digest.

  IMPORTANT: On some systems it is required that RESBUF is correctly
  aligned for a 32 bits value.  */
extern void    *md5_finish_ctx(struct md5_ctx * ctx, void *resbuf);


/* Put result from CTX in first 16 bytes following RESBUF.  The result is
  always in little endian byte order, so that a byte-wise output yields
  to the wanted ASCII representation of the message digest.

  IMPORTANT: On some systems it is required that RESBUF is correctly
  aligned for a 32 bits value.  */
extern void    *md5_read_ctx(const struct md5_ctx * ctx, void *resbuf);


/* Compute MD5 message digest for bytes read from STREAM.  The
  resulting message digest number will be written into the 16 bytes
  beginning at RESBLOCK.  */
extern int      md5_stream(FILE * stream, void *resblock);

/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
  result is always in little endian byte order, so that a byte-wise
  output yields to the wanted ASCII representation of the message
  digest.  */
extern void    *md5_buffer(const char *buffer, size_t len, void *resblock);




extern void     md5_hex(unsigned char *src, char *dst);
extern void     do_md5_file(FILE * src, long start, long bytes, char *hash);
extern void     do_md5_string(char *pass, int passlen, char *hash);




#endif

  Вверх
Unregistered
Дата 28.8.2003, 15:41 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











md5.h
Код

#ifndef _MD5_H
#define _MD5_H

#define Min(a, b)               (((a) < (b)) ? (a): (b))




typedef UINT32 md5_uint32;





/* Structure to save state of computation between the single steps.  */
struct md5_ctx
{
   md5_uint32      A;
   md5_uint32      B;
   md5_uint32      C;
   md5_uint32      D;

   md5_uint32      total[2];
   md5_uint32      buflen;
   char            buffer[128];
};

/*
* The following three functions are build up the low level used in
* the functions `md5_stream' and `md5_buffer'.
*/

/* Initialize structure containing state of computation.
  (RFC 1321, 3.3: Step 3)  */
extern void     md5_init_ctx(struct md5_ctx * ctx);

/* Starting with the result of former calls of this function (or the
  initialization function update the context for the next LEN bytes
  starting at BUFFER.
  It is necessary that LEN is a multiple of 64!!! */
extern void     md5_process_block(const void *buffer, size_t len,
                                 struct md5_ctx * ctx);

/* Starting with the result of former calls of this function (or the
  initialization function update the context for the next LEN bytes
  starting at BUFFER.
  It is NOT required that LEN is a multiple of 64.  */
extern void     md5_process_bytes(const void *buffer, size_t len,
                                 struct md5_ctx * ctx);

/* Process the remaining bytes in the buffer and put result from CTX
  in first 16 bytes following RESBUF.  The result is always in little
  endian byte order, so that a byte-wise output yields to the wanted
  ASCII representation of the message digest.

  IMPORTANT: On some systems it is required that RESBUF is correctly
  aligned for a 32 bits value.  */
extern void    *md5_finish_ctx(struct md5_ctx * ctx, void *resbuf);


/* Put result from CTX in first 16 bytes following RESBUF.  The result is
  always in little endian byte order, so that a byte-wise output yields
  to the wanted ASCII representation of the message digest.

  IMPORTANT: On some systems it is required that RESBUF is correctly
  aligned for a 32 bits value.  */
extern void    *md5_read_ctx(const struct md5_ctx * ctx, void *resbuf);


/* Compute MD5 message digest for bytes read from STREAM.  The
  resulting message digest number will be written into the 16 bytes
  beginning at RESBLOCK.  */
extern int      md5_stream(FILE * stream, void *resblock);

/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
  result is always in little endian byte order, so that a byte-wise
  output yields to the wanted ASCII representation of the message
  digest.  */
extern void    *md5_buffer(const char *buffer, size_t len, void *resblock);




extern void     md5_hex(unsigned char *src, char *dst);
extern void     do_md5_file(FILE * src, long start, long bytes, char *hash);
extern void     do_md5_string(char *pass, int passlen, char *hash);




#endif

  Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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