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 #include <stdio.h>
00029 #include <string.h>
00030 #include <stdlib.h>
00031
00032 #include <sys/utsname.h>
00033 #include <sys/time.h>
00034 #include <unistd.h>
00035 #include <ctype.h>
00036
00037 typedef unsigned char *POINTER;
00038 typedef unsigned short int UINT2;
00039 typedef unsigned long int UINT4;
00040
00041
00042
00043 typedef struct {
00044 UINT4 state[4];
00045 UINT4 count[2];
00046 unsigned char buffer[64];
00047 } MD5_CTX;
00048
00049
00050
00051
00052 static void MD5Init (MD5_CTX *);
00053 static void MD5Update (MD5_CTX *, unsigned char *, unsigned int);
00054 static void MD5Final (unsigned char [16], MD5_CTX *);
00055
00056 static void MD5Transform (UINT4 [4], unsigned char [64]);
00057 static void Encode (unsigned char *, UINT4 *, unsigned int);
00058 static void Decode (UINT4 *, unsigned char *, unsigned int);
00059
00060
00061
00062 #define S11 7
00063 #define S12 12
00064 #define S13 17
00065 #define S14 22
00066 #define S21 5
00067 #define S22 9
00068 #define S23 14
00069 #define S24 20
00070 #define S31 4
00071 #define S32 11
00072 #define S33 16
00073 #define S34 23
00074 #define S41 6
00075 #define S42 10
00076 #define S43 15
00077 #define S44 21
00078
00079 static unsigned char PADDING[64] = {
00080 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00081 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00082 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00083 };
00084
00085
00086
00087 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00088 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00089 #define H(x, y, z) ((x) ^ (y) ^ (z))
00090 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00091
00092
00093
00094 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00095
00096
00097
00098
00099 #define FF(a, b, c, d, x, s, ac) { \
00100 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
00101 (a) = ROTATE_LEFT ((a), (s)); \
00102 (a) += (b); \
00103 }
00104
00105 #define GG(a, b, c, d, x, s, ac) { \
00106 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
00107 (a) = ROTATE_LEFT ((a), (s)); \
00108 (a) += (b); \
00109 }
00110
00111 #define HH(a, b, c, d, x, s, ac) { \
00112 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
00113 (a) = ROTATE_LEFT ((a), (s)); \
00114 (a) += (b); \
00115 }
00116
00117 #define II(a, b, c, d, x, s, ac) { \
00118 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
00119 (a) = ROTATE_LEFT ((a), (s)); \
00120 (a) += (b); \
00121 }
00122
00123
00124
00125
00126
00127 static void MD5Init (MD5_CTX * context)
00128 {
00129 context->count[0] = context->count[1] = 0;
00130
00131
00132
00133 context->state[0] = 0x67452301;
00134 context->state[1] = 0xefcdab89;
00135 context->state[2] = 0x98badcfe;
00136 context->state[3] = 0x10325476;
00137 }
00138
00139
00140
00141
00142
00143
00144
00145 static void MD5Update (MD5_CTX * context, unsigned char * input,
00146 unsigned int inputLen )
00147 {
00148 unsigned int i, index, partLen;
00149
00150
00151
00152 index = (unsigned int)((context->count[0] >> 3) & 0x3F);
00153
00154
00155
00156 if( (context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3) )
00157 context->count[1]++;
00158
00159 context->count[1] += ((UINT4)inputLen >> 29);
00160
00161 partLen = 64 - index;
00162
00163
00164
00165 if (inputLen >= partLen) {
00166
00167 memcpy ((POINTER)&context->buffer[index], (POINTER)input, partLen);
00168
00169 MD5Transform (context->state, context->buffer);
00170
00171 for (i = partLen; i + 63 < inputLen; i += 64)
00172 MD5Transform (context->state, &input[i]);
00173
00174 index = 0;
00175 }
00176 else
00177 i = 0;
00178
00179
00180
00181 memcpy ((POINTER)&context->buffer[index], (POINTER)&input[i],
00182 inputLen-i);
00183 }
00184
00185
00186
00187
00188
00189
00190 static void MD5Final (unsigned char digest[16], MD5_CTX * context)
00191 {
00192 unsigned char bits[8];
00193 unsigned int index, padLen;
00194
00195
00196
00197 Encode (bits, context->count, 8);
00198
00199
00200
00201 index = (unsigned int)((context->count[0] >> 3) & 0x3f);
00202 padLen = (index < 56) ? (56 - index) : (120 - index);
00203 MD5Update (context, PADDING, padLen);
00204
00205
00206
00207 MD5Update (context, bits, 8);
00208
00209
00210
00211 Encode (digest, context->state, 16);
00212
00213
00214
00215 memset ((POINTER)context, 0, sizeof (*context));
00216 }
00217
00218
00219
00220
00221
00222 static void MD5Transform (UINT4 state[4], unsigned char block[64])
00223 {
00224 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00225
00226 Decode (x, block, 64);
00227
00228
00229
00230 FF (a, b, c, d, x[ 0], S11, 0xd76aa478);
00231 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756);
00232 FF (c, d, a, b, x[ 2], S13, 0x242070db);
00233 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee);
00234 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf);
00235 FF (d, a, b, c, x[ 5], S12, 0x4787c62a);
00236 FF (c, d, a, b, x[ 6], S13, 0xa8304613);
00237 FF (b, c, d, a, x[ 7], S14, 0xfd469501);
00238 FF (a, b, c, d, x[ 8], S11, 0x698098d8);
00239 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af);
00240 FF (c, d, a, b, x[10], S13, 0xffff5bb1);
00241 FF (b, c, d, a, x[11], S14, 0x895cd7be);
00242 FF (a, b, c, d, x[12], S11, 0x6b901122);
00243 FF (d, a, b, c, x[13], S12, 0xfd987193);
00244 FF (c, d, a, b, x[14], S13, 0xa679438e);
00245 FF (b, c, d, a, x[15], S14, 0x49b40821);
00246
00247
00248
00249 GG (a, b, c, d, x[ 1], S21, 0xf61e2562);
00250 GG (d, a, b, c, x[ 6], S22, 0xc040b340);
00251 GG (c, d, a, b, x[11], S23, 0x265e5a51);
00252 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa);
00253 GG (a, b, c, d, x[ 5], S21, 0xd62f105d);
00254 GG (d, a, b, c, x[10], S22, 0x2441453);
00255 GG (c, d, a, b, x[15], S23, 0xd8a1e681);
00256 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8);
00257 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6);
00258 GG (d, a, b, c, x[14], S22, 0xc33707d6);
00259 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87);
00260 GG (b, c, d, a, x[ 8], S24, 0x455a14ed);
00261 GG (a, b, c, d, x[13], S21, 0xa9e3e905);
00262 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8);
00263 GG (c, d, a, b, x[ 7], S23, 0x676f02d9);
00264 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a);
00265
00266
00267
00268 HH (a, b, c, d, x[ 5], S31, 0xfffa3942);
00269 HH (d, a, b, c, x[ 8], S32, 0x8771f681);
00270 HH (c, d, a, b, x[11], S33, 0x6d9d6122);
00271 HH (b, c, d, a, x[14], S34, 0xfde5380c);
00272 HH (a, b, c, d, x[ 1], S31, 0xa4beea44);
00273 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9);
00274 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60);
00275 HH (b, c, d, a, x[10], S34, 0xbebfbc70);
00276 HH (a, b, c, d, x[13], S31, 0x289b7ec6);
00277 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa);
00278 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085);
00279 HH (b, c, d, a, x[ 6], S34, 0x4881d05);
00280 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039);
00281 HH (d, a, b, c, x[12], S32, 0xe6db99e5);
00282 HH (c, d, a, b, x[15], S33, 0x1fa27cf8);
00283 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665);
00284
00285
00286
00287 II (a, b, c, d, x[ 0], S41, 0xf4292244);
00288 II (d, a, b, c, x[ 7], S42, 0x432aff97);
00289 II (c, d, a, b, x[14], S43, 0xab9423a7);
00290 II (b, c, d, a, x[ 5], S44, 0xfc93a039);
00291 II (a, b, c, d, x[12], S41, 0x655b59c3);
00292 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92);
00293 II (c, d, a, b, x[10], S43, 0xffeff47d);
00294 II (b, c, d, a, x[ 1], S44, 0x85845dd1);
00295 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f);
00296 II (d, a, b, c, x[15], S42, 0xfe2ce6e0);
00297 II (c, d, a, b, x[ 6], S43, 0xa3014314);
00298 II (b, c, d, a, x[13], S44, 0x4e0811a1);
00299 II (a, b, c, d, x[ 4], S41, 0xf7537e82);
00300 II (d, a, b, c, x[11], S42, 0xbd3af235);
00301 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb);
00302 II (b, c, d, a, x[ 9], S44, 0xeb86d391);
00303
00304 state[0] += a;
00305 state[1] += b;
00306 state[2] += c;
00307 state[3] += d;
00308
00309
00310
00311 memset ((POINTER)x, 0, sizeof (x));
00312 }
00313
00314
00315
00316
00317
00318
00319 static void Encode (unsigned char *output, UINT4 *input, unsigned int len)
00320 {
00321 unsigned int i, j;
00322
00323 for (i = 0, j = 0; j < len; i++, j += 4) {
00324 output[j] = (unsigned char)(input[i] & 0xff);
00325 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
00326 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
00327 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
00328 }
00329 }
00330
00331
00332
00333
00334
00335
00336 static void Decode (UINT4 *output, unsigned char *input, unsigned int len)
00337 {
00338 unsigned int i, j;
00339
00340 for (i = 0, j = 0; j < len; i++, j += 4)
00341 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
00342 (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24) ;
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 static char * MD5_static_printf( unsigned char digest[16] )
00354 {
00355 static char st[33] ;
00356
00357 sprintf(st,
00358 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" ,
00359 digest[0] , digest[1] , digest[2] , digest[3] , digest[4] ,
00360 digest[5] , digest[6] , digest[7] , digest[8] , digest[9] ,
00361 digest[10], digest[11], digest[12], digest[13], digest[14],
00362 digest[15]
00363 ) ;
00364
00365 return st ;
00366 }
00367
00368
00369
00370
00371
00372 char * MD5_static_array( int n , char * bytes )
00373 {
00374 MD5_CTX context;
00375 unsigned char digest[16];
00376
00377 if( n < 0 || bytes == NULL ) return NULL ;
00378
00379 MD5Init( &context ) ;
00380 MD5Update( &context, bytes, n ) ;
00381 MD5Final( digest, &context ) ;
00382
00383 return MD5_static_printf(digest) ;
00384 }
00385
00386 char * MD5_malloc_array( int n , char * bytes )
00387 {
00388 char *st , *dy ;
00389 st = MD5_static_array( n , bytes ) ;
00390 if( st == NULL ) return NULL ;
00391 dy = (char *) malloc(33) ; strcpy(dy,st) ; return dy ;
00392 }
00393
00394
00395
00396 char * MD5_static_string( char * string )
00397 {
00398 if( string == NULL ) return NULL ;
00399 return MD5_static_array( strlen(string) , string ) ;
00400 }
00401
00402 char * MD5_malloc_string( char * string )
00403 {
00404 if( string == NULL ) return NULL ;
00405 return (char*)MD5_malloc_array( strlen(string) , string ) ;
00406 }
00407
00408
00409
00410
00411
00412 char * MD5_static_file(char * filename)
00413 {
00414 FILE *file;
00415 MD5_CTX context;
00416 int len;
00417 unsigned char buffer[1024] ;
00418 unsigned char digest[16] ;
00419
00420 if( (file = fopen (filename, "rb")) == NULL ) return NULL ;
00421
00422 MD5Init( &context ) ;
00423
00424 while( len = fread(buffer, 1, 1024, file) )
00425 MD5Update( &context, buffer, len ) ;
00426
00427 MD5Final( digest, &context );
00428 fclose (file);
00429
00430 return MD5_static_printf( digest ) ;
00431 }
00432
00433 char * MD5_malloc_file(char * filename)
00434 {
00435 char *st , *dy ;
00436
00437 st = MD5_static_file( filename ) ;
00438 if( st == NULL ) return NULL ;
00439 dy = (char *) malloc(33) ; strcpy(dy,st) ; return dy ;
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 extern void B64_to_base64( int, char *, int *, char ** ) ;
00451
00452 static char * MD5_to_B64( unsigned char digest[16] )
00453 {
00454 int nb64=0 ; char *b64=NULL ;
00455
00456 B64_to_base64( 16 , (char *)digest , &nb64 , &b64 ) ;
00457 if( nb64 <= 0 || b64 == NULL ) return NULL ;
00458 b64[nb64-3] = '\0' ;
00459 return b64 ;
00460 }
00461
00462 char * MD5_B64_array( int n , char * bytes )
00463 {
00464 MD5_CTX context;
00465 unsigned char digest[16];
00466
00467 if( n < 0 || bytes == NULL ) return NULL ;
00468
00469 MD5Init( &context ) ;
00470 MD5Update( &context, bytes, n ) ;
00471 MD5Final( digest, &context ) ;
00472
00473 return MD5_to_B64( digest ) ;
00474 }
00475
00476 char * MD5_B64_string( char * string )
00477 {
00478 if( string == NULL ) return NULL ;
00479 return MD5_B64_array( strlen(string) , string ) ;
00480 }
00481
00482 char * MD5_B64_file(char * filename)
00483 {
00484 FILE *file;
00485 MD5_CTX context;
00486 int len;
00487 unsigned char buffer[1024] ;
00488 unsigned char digest[16] ;
00489
00490 if( (file = fopen (filename, "rb")) == NULL ) return NULL ;
00491
00492 MD5Init( &context ) ;
00493
00494 while( len = fread(buffer, 1, 1024, file) )
00495 MD5Update( &context, buffer, len ) ;
00496
00497 MD5Final( digest, &context );
00498 fclose (file);
00499
00500 return MD5_to_B64( digest ) ;
00501 }
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516 char * UNIQ_idcode(void)
00517 {
00518 struct utsname ubuf ;
00519 struct timeval tv ;
00520 int nn , ii ;
00521 int nbuf ;
00522 char *buf , *idc , *eee ;
00523 static int ncall=0 ;
00524
00525
00526
00527 nn = uname( &ubuf ) ;
00528 if( nn == -1 ){
00529 strcpy( ubuf.nodename , "E" ) ;
00530 strcpy( ubuf.sysname , "L" ) ;
00531 strcpy( ubuf.release , "V" ) ;
00532 strcpy( ubuf.version , "I" ) ;
00533 strcpy( ubuf.machine , "S" ) ;
00534 }
00535
00536
00537
00538 nbuf = strlen(ubuf.nodename)+strlen(ubuf.sysname)
00539 +strlen(ubuf.release )+strlen(ubuf.version)+strlen(ubuf.machine) ;
00540
00541 buf = AFMALL(char, nbuf+64) ;
00542 strcpy(buf,ubuf.nodename) ;
00543 strcat(buf,ubuf.sysname ) ;
00544 strcat(buf,ubuf.release ) ;
00545 strcat(buf,ubuf.version ) ;
00546 strcat(buf,ubuf.machine ) ;
00547
00548 idc = AFMALL(char, 32) ;
00549
00550
00551
00552 nn = gettimeofday( &tv , NULL ) ;
00553 if( nn == -1 ){
00554 tv.tv_sec = (long) buf ;
00555 tv.tv_usec = (long) idc ;
00556 }
00557
00558 sprintf(buf+nbuf,"%d%d%d%d",
00559 (int)tv.tv_sec,(int)tv.tv_usec,(int)getpid(),ncall) ;
00560 ncall++ ;
00561
00562
00563
00564 eee = getenv("IDCODE_PREFIX") ;
00565 if( eee != NULL && isalpha(eee[0]) ){
00566 for( ii=0 ; ii < 3 && isalnum(eee[ii]) ; ii++ )
00567 idc[ii] = eee[ii] ;
00568 } else {
00569 strcpy(idc,"NIH") ;
00570 }
00571 strcat(idc,"_") ;
00572
00573
00574
00575 eee = MD5_B64_string( buf ) ;
00576 if( eee != NULL ){
00577 int nn = strlen(eee) ;
00578 for( ii=0 ; ii < nn ; ii++ ){
00579 if( eee[ii] == '/' ) eee[ii] = '-' ;
00580 else if( eee[ii] == '+' ) eee[ii] = '_' ;
00581 }
00582 strcat(idc,eee) ;
00583 } else {
00584 nn = strlen(idc) ;
00585 sprintf(idc+nn,"%d_%d",(int)tv.tv_sec,(int)tv.tv_usec) ;
00586 }
00587
00588
00589
00590 if( eee != NULL ) free(eee) ;
00591 free(buf) ; return idc ;
00592 }
00593
00594
00595
00596
00597
00598 void UNIQ_idcode_fill( char *idc )
00599 {
00600 char *bbb ;
00601 if( idc == NULL ) return ;
00602 bbb = UNIQ_idcode() ;
00603 strcpy(idc,bbb) ; free(bbb) ; return ;
00604 }
00605
00606