⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_md5.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
字号:
/*** SQLite uses this code for testing only.  It is not a part of** the SQLite library.  This file implements two new TCL commands** "md5" and "md5file" that compute md5 checksums on arbitrary text** and on complete files.  These commands are used by the "testfixture"** program to help verify the correct operation of the SQLite library.**** The original use of these TCL commands was to test the ROLLBACK** feature of SQLite.  First compute the MD5-checksum of the database.** Then make some changes but rollback the changes rather than commit** them.  Compute a second MD5-checksum of the file and verify that the** two checksums are the same.  Such is the original use of this code.** New uses may have been added since this comment was written.*//* * This code implements the MD5 message-digest algorithm. * The algorithm is due to Ron Rivest.  This code was * written by Colin Plumb in 1993, no copyright is claimed. * This code is in the public domain; do with it what you wish. * * Equivalent code is available from RSA Data Security, Inc. * This code has been tested against that, and is equivalent, * except that you don't need to include two pages of legalese * with every copy. * * To compute the message digest of a chunk of bytes, declare an * MD5Context structure, pass it to MD5Init, call MD5Update as * needed on buffers full of bytes, and then call MD5Final, which * will fill a supplied 16-byte array with the digest. */#include <tcl.h>#include <string.h>#include "sqlite3.h"/* * If compiled on a machine that doesn't have a 32-bit integer, * you just set "uint32" to the appropriate datatype for an * unsigned 32-bit integer.  For example: * *       cc -Duint32='unsigned long' md5.c * */#ifndef uint32#  define uint32 unsigned int#endifstruct Context {  int isInit;  uint32 buf[4];  uint32 bits[2];  unsigned char in[64];};typedef struct Context MD5Context;/* * Note: this code is harmless on little-endian machines. */static void byteReverse (unsigned char *buf, unsigned longs){        uint32 t;        do {                t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |                            ((unsigned)buf[1]<<8 | buf[0]);                *(uint32 *)buf = t;                buf += 4;        } while (--longs);}/* The four core functions - F1 is optimized somewhat *//* #define F1(x, y, z) (x & y | ~x & z) */#define F1(x, y, z) (z ^ (x & (y ^ z)))#define F2(x, y, z) F1(z, x, y)#define F3(x, y, z) (x ^ y ^ z)#define F4(x, y, z) (y ^ (x | ~z))/* This is the central step in the MD5 algorithm. */#define MD5STEP(f, w, x, y, z, data, s) \        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )/* * The core of the MD5 algorithm, this alters an existing MD5 hash to * reflect the addition of 16 longwords of new data.  MD5Update blocks * the data and converts bytes into longwords for this routine. */static void MD5Transform(uint32 buf[4], const uint32 in[16]){        register uint32 a, b, c, d;        a = buf[0];        b = buf[1];        c = buf[2];        d = buf[3];        MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);        MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);        MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);        MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);        MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);        MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);        MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);        MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);        MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);        MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);        MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);        MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);        MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);        MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);        MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);        MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);        MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);        MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);        MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);        MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);        MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);        MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);        MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);        MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);        MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);        MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);        MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);        MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);        MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);        MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);        MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);        MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);        MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);        MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);        MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);        MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);        MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);        MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);        MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);        MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);        MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);        MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);        MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);        MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);        MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);        MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);        MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);        MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);        MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);        MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);        MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);        MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);        MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);        MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);        MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);        MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);        MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);        MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);        MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);        MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);        MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);        MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);        MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);        MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);        buf[0] += a;        buf[1] += b;        buf[2] += c;        buf[3] += d;}/* * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious * initialization constants. */static void MD5Init(MD5Context *ctx){	ctx->isInit = 1;        ctx->buf[0] = 0x67452301;        ctx->buf[1] = 0xefcdab89;        ctx->buf[2] = 0x98badcfe;        ctx->buf[3] = 0x10325476;        ctx->bits[0] = 0;        ctx->bits[1] = 0;}/* * Update context to reflect the concatenation of another buffer full * of bytes. */static void MD5Update(MD5Context *pCtx, const unsigned char *buf, unsigned int len){        struct Context *ctx = (struct Context *)pCtx;        uint32 t;        /* Update bitcount */        t = ctx->bits[0];        if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)                ctx->bits[1]++; /* Carry from low to high */        ctx->bits[1] += len >> 29;        t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */        /* Handle any leading odd-sized chunks */        if ( t ) {                unsigned char *p = (unsigned char *)ctx->in + t;                t = 64-t;                if (len < t) {                        memcpy(p, buf, len);                        return;                }                memcpy(p, buf, t);                byteReverse(ctx->in, 16);                MD5Transform(ctx->buf, (uint32 *)ctx->in);                buf += t;                len -= t;        }        /* Process data in 64-byte chunks */        while (len >= 64) {                memcpy(ctx->in, buf, 64);                byteReverse(ctx->in, 16);                MD5Transform(ctx->buf, (uint32 *)ctx->in);                buf += 64;                len -= 64;        }        /* Handle any remaining bytes of data. */        memcpy(ctx->in, buf, len);}/* * Final wrapup - pad to 64-byte boundary with the bit pattern  * 1 0* (64-bit count of bits processed, MSB-first) */static void MD5Final(unsigned char digest[16], MD5Context *pCtx){        struct Context *ctx = (struct Context *)pCtx;        unsigned count;        unsigned char *p;        /* Compute number of bytes mod 64 */        count = (ctx->bits[0] >> 3) & 0x3F;        /* Set the first char of padding to 0x80.  This is safe since there is           always at least one byte free */        p = ctx->in + count;        *p++ = 0x80;        /* Bytes of padding needed to make 64 bytes */        count = 64 - 1 - count;        /* Pad out to 56 mod 64 */        if (count < 8) {                /* Two lots of padding:  Pad the first block to 64 bytes */                memset(p, 0, count);                byteReverse(ctx->in, 16);                MD5Transform(ctx->buf, (uint32 *)ctx->in);                /* Now fill the next block with 56 bytes */                memset(ctx->in, 0, 56);        } else {                /* Pad block to 56 bytes */                memset(p, 0, count-8);        }        byteReverse(ctx->in, 14);        /* Append length in bits and transform */        ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];        ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];        MD5Transform(ctx->buf, (uint32 *)ctx->in);        byteReverse((unsigned char *)ctx->buf, 4);        memcpy(digest, ctx->buf, 16);        memset(ctx, 0, sizeof(ctx));    /* In case it's sensitive */}/*** Convert a digest into base-16.  digest should be declared as** "unsigned char digest[16]" in the calling function.  The MD5** digest is stored in the first 16 bytes.  zBuf should** be "char zBuf[33]".*/static void DigestToBase16(unsigned char *digest, char *zBuf){  static char const zEncode[] = "0123456789abcdef";  int i, j;  for(j=i=0; i<16; i++){    int a = digest[i];    zBuf[j++] = zEncode[(a>>4)&0xf];    zBuf[j++] = zEncode[a & 0xf];  }  zBuf[j] = 0;}/*** A TCL command for md5.  The argument is the text to be hashed.  The** Result is the hash in base64.  */static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){  MD5Context ctx;  unsigned char digest[16];  if( argc!=2 ){    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],         " TEXT\"", 0);    return TCL_ERROR;  }  MD5Init(&ctx);  MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1]));  MD5Final(digest, &ctx);  DigestToBase16(digest, interp->result);  return TCL_OK;}/*** A TCL command to take the md5 hash of a file.  The argument is the** name of the file.*/static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){  FILE *in;  MD5Context ctx;  unsigned char digest[16];  char zBuf[10240];  if( argc!=2 ){    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],         " FILENAME\"", 0);    return TCL_ERROR;  }  in = fopen(argv[1],"rb");  if( in==0 ){    Tcl_AppendResult(interp,"unable to open file \"", argv[1],          "\" for reading", 0);    return TCL_ERROR;  }  MD5Init(&ctx);  for(;;){    int n;    n = fread(zBuf, 1, sizeof(zBuf), in);    if( n<=0 ) break;    MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n);  }  fclose(in);  MD5Final(digest, &ctx);  DigestToBase16(digest, interp->result);  return TCL_OK;}/*** Register the two TCL commands above with the TCL interpreter.*/int Md5_Init(Tcl_Interp *interp){  Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd, 0, 0);  Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd, 0, 0);  return TCL_OK;}/*** During testing, the special md5sum() aggregate function is available.** inside SQLite.  The following routines implement that function.*/static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){  MD5Context *p;  int i;  if( argc<1 ) return;  p = sqlite3_aggregate_context(context, sizeof(*p));  if( p==0 ) return;  if( !p->isInit ){    MD5Init(p);  }  for(i=0; i<argc; i++){    const char *zData = (char*)sqlite3_value_text(argv[i]);    if( zData ){      MD5Update(p, (unsigned char*)zData, strlen(zData));    }  }}static void md5finalize(sqlite3_context *context){  MD5Context *p;  unsigned char digest[16];  char zBuf[33];  p = sqlite3_aggregate_context(context, sizeof(*p));  MD5Final(digest,p);  DigestToBase16(digest, zBuf);  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);}void Md5_Register(sqlite3 *db){  sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0,       md5step, md5finalize);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -