00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <tcl.h>
00032 #include <string.h>
00033 #include "sqlite.h"
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifndef uint32
00044 # define uint32 unsigned int
00045 #endif
00046
00047 struct Context {
00048 uint32 buf[4];
00049 uint32 bits[2];
00050 unsigned char in[64];
00051 };
00052 typedef char MD5Context[88];
00053
00054
00055
00056
00057 static void byteReverse (unsigned char *buf, unsigned longs){
00058 uint32 t;
00059 do {
00060 t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
00061 ((unsigned)buf[1]<<8 | buf[0]);
00062 *(uint32 *)buf = t;
00063 buf += 4;
00064 } while (--longs);
00065 }
00066
00067
00068
00069 #define F1(x, y, z) (z ^ (x & (y ^ z)))
00070 #define F2(x, y, z) F1(z, x, y)
00071 #define F3(x, y, z) (x ^ y ^ z)
00072 #define F4(x, y, z) (y ^ (x | ~z))
00073
00074
00075 #define MD5STEP(f, w, x, y, z, data, s) \
00076 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
00077
00078
00079
00080
00081
00082
00083 static void MD5Transform(uint32 buf[4], const uint32 in[16]){
00084 register uint32 a, b, c, d;
00085
00086 a = buf[0];
00087 b = buf[1];
00088 c = buf[2];
00089 d = buf[3];
00090
00091 MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
00092 MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
00093 MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
00094 MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
00095 MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
00096 MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
00097 MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
00098 MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
00099 MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7);
00100 MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
00101 MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
00102 MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
00103 MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7);
00104 MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
00105 MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
00106 MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
00107
00108 MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
00109 MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9);
00110 MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
00111 MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
00112 MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
00113 MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9);
00114 MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
00115 MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
00116 MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
00117 MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9);
00118 MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
00119 MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
00120 MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5);
00121 MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
00122 MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
00123 MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
00124
00125 MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
00126 MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
00127 MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
00128 MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
00129 MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
00130 MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
00131 MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
00132 MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
00133 MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4);
00134 MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
00135 MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
00136 MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
00137 MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
00138 MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
00139 MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
00140 MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
00141
00142 MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6);
00143 MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
00144 MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
00145 MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
00146 MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6);
00147 MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
00148 MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
00149 MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
00150 MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
00151 MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
00152 MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
00153 MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
00154 MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
00155 MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
00156 MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
00157 MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
00158
00159 buf[0] += a;
00160 buf[1] += b;
00161 buf[2] += c;
00162 buf[3] += d;
00163 }
00164
00165
00166
00167
00168
00169 static void MD5Init(MD5Context *pCtx){
00170 struct Context *ctx = (struct Context *)pCtx;
00171 ctx->buf[0] = 0x67452301;
00172 ctx->buf[1] = 0xefcdab89;
00173 ctx->buf[2] = 0x98badcfe;
00174 ctx->buf[3] = 0x10325476;
00175 ctx->bits[0] = 0;
00176 ctx->bits[1] = 0;
00177 }
00178
00179
00180
00181
00182
00183 static
00184 void MD5Update(MD5Context *pCtx, const unsigned char *buf, unsigned int len){
00185 struct Context *ctx = (struct Context *)pCtx;
00186 uint32 t;
00187
00188
00189
00190 t = ctx->bits[0];
00191 if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
00192 ctx->bits[1]++;
00193 ctx->bits[1] += len >> 29;
00194
00195 t = (t >> 3) & 0x3f;
00196
00197
00198
00199 if ( t ) {
00200 unsigned char *p = (unsigned char *)ctx->in + t;
00201
00202 t = 64-t;
00203 if (len < t) {
00204 memcpy(p, buf, len);
00205 return;
00206 }
00207 memcpy(p, buf, t);
00208 byteReverse(ctx->in, 16);
00209 MD5Transform(ctx->buf, (uint32 *)ctx->in);
00210 buf += t;
00211 len -= t;
00212 }
00213
00214
00215
00216 while (len >= 64) {
00217 memcpy(ctx->in, buf, 64);
00218 byteReverse(ctx->in, 16);
00219 MD5Transform(ctx->buf, (uint32 *)ctx->in);
00220 buf += 64;
00221 len -= 64;
00222 }
00223
00224
00225
00226 memcpy(ctx->in, buf, len);
00227 }
00228
00229
00230
00231
00232
00233 static void MD5Final(unsigned char digest[16], MD5Context *pCtx){
00234 struct Context *ctx = (struct Context *)pCtx;
00235 unsigned count;
00236 unsigned char *p;
00237
00238
00239 count = (ctx->bits[0] >> 3) & 0x3F;
00240
00241
00242
00243 p = ctx->in + count;
00244 *p++ = 0x80;
00245
00246
00247 count = 64 - 1 - count;
00248
00249
00250 if (count < 8) {
00251
00252 memset(p, 0, count);
00253 byteReverse(ctx->in, 16);
00254 MD5Transform(ctx->buf, (uint32 *)ctx->in);
00255
00256
00257 memset(ctx->in, 0, 56);
00258 } else {
00259
00260 memset(p, 0, count-8);
00261 }
00262 byteReverse(ctx->in, 14);
00263
00264
00265 ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
00266 ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];
00267
00268 MD5Transform(ctx->buf, (uint32 *)ctx->in);
00269 byteReverse((unsigned char *)ctx->buf, 4);
00270 memcpy(digest, ctx->buf, 16);
00271 memset(ctx, 0, sizeof(ctx));
00272 }
00273
00274
00275
00276
00277
00278
00279
00280 static void DigestToBase16(unsigned char *digest, char *zBuf){
00281 static char const zEncode[] = "0123456789abcdef";
00282 int i, j;
00283
00284 for(j=i=0; i<16; i++){
00285 int a = digest[i];
00286 zBuf[j++] = zEncode[(a>>4)&0xf];
00287 zBuf[j++] = zEncode[a & 0xf];
00288 }
00289 zBuf[j] = 0;
00290 }
00291
00292
00293
00294
00295
00296 static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){
00297 MD5Context ctx;
00298 unsigned char digest[16];
00299
00300 if( argc!=2 ){
00301 Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
00302 " TEXT\"", 0);
00303 return TCL_ERROR;
00304 }
00305 MD5Init(&ctx);
00306 MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1]));
00307 MD5Final(digest, &ctx);
00308 DigestToBase16(digest, interp->result);
00309 return TCL_OK;
00310 }
00311
00312
00313
00314
00315
00316 static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){
00317 FILE *in;
00318 MD5Context ctx;
00319 unsigned char digest[16];
00320 char zBuf[10240];
00321
00322 if( argc!=2 ){
00323 Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
00324 " FILENAME\"", 0);
00325 return TCL_ERROR;
00326 }
00327 in = fopen(argv[1],"rb");
00328 if( in==0 ){
00329 Tcl_AppendResult(interp,"unable to open file \"", argv[1],
00330 "\" for reading", 0);
00331 return TCL_ERROR;
00332 }
00333 MD5Init(&ctx);
00334 for(;;){
00335 int n;
00336 n = fread(zBuf, 1, sizeof(zBuf), in);
00337 if( n<=0 ) break;
00338 MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
00339 }
00340 fclose(in);
00341 MD5Final(digest, &ctx);
00342 DigestToBase16(digest, interp->result);
00343 return TCL_OK;
00344 }
00345
00346
00347
00348
00349 int Md5_Init(Tcl_Interp *interp){
00350 Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd, 0, 0);
00351 Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd, 0, 0);
00352 return TCL_OK;
00353 }
00354
00355
00356
00357
00358
00359 static void md5step(sqlite_func *context, int argc, const char **argv){
00360 MD5Context *p;
00361 int i;
00362 if( argc<1 ) return;
00363 p = sqlite_aggregate_context(context, sizeof(*p));
00364 if( p==0 ) return;
00365 if( sqlite_aggregate_count(context)==1 ){
00366 MD5Init(p);
00367 }
00368 for(i=0; i<argc; i++){
00369 if( argv[i] ){
00370 MD5Update(p, (unsigned char*)argv[i], strlen(argv[i]));
00371 }
00372 }
00373 }
00374 static void md5finalize(sqlite_func *context){
00375 MD5Context *p;
00376 unsigned char digest[16];
00377 char zBuf[33];
00378 p = sqlite_aggregate_context(context, sizeof(*p));
00379 MD5Final(digest,p);
00380 DigestToBase16(digest, zBuf);
00381 sqlite_set_result_string(context, zBuf, strlen(zBuf));
00382 }
00383 void Md5_Register(sqlite *db){
00384 sqlite_create_aggregate(db, "md5sum", -1, md5step, md5finalize, 0);
00385 }