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 #include <sys/time.h>
00026 #include <stdint.h>
00027 #include <time.h>
00028
00029 #ifndef WIN32
00030 # include <sys/utsname.h>
00031 # include <sys/types.h>
00032 # include <unistd.h>
00033 #endif
00034
00035 #ifdef HAVE_BYTESWAP_H
00036 # include <byteswap.h>
00037 #else
00038 # ifndef bswap_16
00039 # define bswap_16(value) ((((value) & 0xff) << 8) | ((value) >> 8))
00040 # endif
00041 # ifndef bswap_32
00042 # define bswap_32(value) (((uint32_t)bswap_16((uint16_t)((value) & 0xffff)) << 16)\
00043 | (uint32_t)bswap_16((uint16_t)((value) >> 16)))
00044 # endif
00045 # ifndef bswap_64
00046 # define bswap_64(value) (((uint64_t)bswap_32((uint32_t)((value) & 0xffffffff)) << 32)\
00047 | (uint64_t)bswap_32((uint32_t)((value) >> 32)))
00048 # endif
00049 #endif
00050
00051
00052 #ifdef WORDS_BIGENDIAN
00053 #define be2me_16(x) (x)
00054 #define be2me_32(x) (x)
00055 #define be2me_64(x) (x)
00056 #define le2me_16(x) bswap_16(x)
00057 #define le2me_32(x) bswap_32(x)
00058 #define le2me_64(x) bswap_64(x)
00059 #else
00060 #define be2me_16(x) bswap_16(x)
00061 #define be2me_32(x) bswap_32(x)
00062 #define be2me_64(x) bswap_64(x)
00063 #define le2me_16(x) (x)
00064 #define le2me_32(x) (x)
00065 #define le2me_64(x) (x)
00066 #endif
00067
00068 typedef struct AVMD5{
00069 uint64_t len;
00070 uint8_t block[64];
00071 uint32_t ABCD[4];
00072 } AVMD5;
00073
00074 static const uint8_t S[4][4] = {
00075 { 7, 12, 17, 22 },
00076 { 5, 9, 14, 20 },
00077 { 4, 11, 16, 23 },
00078 { 6, 10, 15, 21 }
00079 };
00080
00081 static const uint32_t T[64] = {
00082 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
00083 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
00084 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
00085 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
00086
00087 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
00088 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
00089 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
00090 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
00091
00092 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
00093 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
00094 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
00095 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
00096
00097 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
00098 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
00099 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
00100 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
00101 };
00102
00103 #define CORE(i, a, b, c, d) \
00104 t = S[i>>4][i&3];\
00105 a += T[i];\
00106 \
00107 if(i<32){\
00108 if(i<16) a += (d ^ (b&(c^d))) + X[ i &15 ];\
00109 else a += (c ^ (d&(c^b))) + X[ (1+5*i)&15 ];\
00110 }else{\
00111 if(i<48) a += (b^c^d) + X[ (5+3*i)&15 ];\
00112 else a += (c^(b|~d)) + X[ ( 7*i)&15 ];\
00113 }\
00114 a = b + (( a << t ) | ( a >> (32 - t) ));
00115
00116 static void body(uint32_t ABCD[4], uint32_t X[16]){
00117
00118 int t;
00119 #ifdef WORDS_BIGENDIAN
00120 int i;
00121 #endif
00122 unsigned int a= ABCD[3];
00123 unsigned int b= ABCD[2];
00124 unsigned int c= ABCD[1];
00125 unsigned int d= ABCD[0];
00126
00127 #ifdef WORDS_BIGENDIAN
00128 for(i=0; i<16; i++)
00129 X[i]= bswap_32(X[i]);
00130 #endif
00131
00132 #define CORE2(i) CORE(i,a,b,c,d) CORE((i+1),d,a,b,c) CORE((i+2),c,d,a,b) CORE((i+3),b,c,d,a)
00133 #define CORE4(i) CORE2(i) CORE2((i+4)) CORE2((i+8)) CORE2((i+12))
00134 CORE4(0) CORE4(16) CORE4(32) CORE4(48)
00135
00136 ABCD[0] += d;
00137 ABCD[1] += c;
00138 ABCD[2] += b;
00139 ABCD[3] += a;
00140 }
00141
00142 static void av_md5_init(AVMD5 *ctx){
00143 ctx->len = 0;
00144
00145 ctx->ABCD[0] = 0x10325476;
00146 ctx->ABCD[1] = 0x98badcfe;
00147 ctx->ABCD[2] = 0xefcdab89;
00148 ctx->ABCD[3] = 0x67452301;
00149 }
00150
00151 static void av_md5_update(AVMD5 *ctx, const uint8_t *src, const int len){
00152 int i, j;
00153
00154 j= ctx->len & 63;
00155 ctx->len += len;
00156
00157 for( i = 0; i < len; i++ ){
00158 ctx->block[j++] = src[i];
00159 if( 64 == j ){
00160 body(ctx->ABCD, (uint32_t*) ctx->block);
00161 j = 0;
00162 }
00163 }
00164 }
00165
00166 static void av_md5_final(AVMD5 *ctx, uint8_t *dst){
00167 int i;
00168 uint64_t finalcount= le2me_64(ctx->len<<3);
00169
00170 av_md5_update(ctx, (uint8_t *)"\200", 1);
00171 while((ctx->len & 63)<56)
00172 av_md5_update(ctx, (uint8_t *)"", 1);
00173
00174 av_md5_update(ctx, (uint8_t *)&finalcount, 8);
00175
00176 for(i=0; i<4; i++)
00177 ((uint32_t*)dst)[i]= le2me_32(ctx->ABCD[3-i]);
00178 }
00179
00180 static void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len){
00181 AVMD5 ctx[1];
00182
00183 av_md5_init(ctx);
00184 av_md5_update(ctx, src, len);
00185 av_md5_final(ctx, dst);
00186 }
00187
00188 static uint32_t md_32(char *string, int length)
00189 {
00190 int hash[4];
00191 av_md5_sum((uint8_t *)hash, (uint8_t *) string, length);
00192 return hash[0]^hash[1]^hash[2]^hash[3];
00193 }
00194
00195 #ifndef WIN32
00196 uint32_t random32(int type)
00197 {
00198 struct {
00199 int type;
00200 struct timeval tv;
00201 clock_t cpu;
00202 pid_t pid;
00203 uint32_t hid;
00204 uid_t uid;
00205 gid_t gid;
00206 struct utsname name;
00207 } s;
00208
00209 gettimeofday(&s.tv, NULL);
00210 uname(&s.name);
00211 s.type = type;
00212 s.cpu = clock();
00213 s.pid = getpid();
00214 s.hid = gethostid();
00215 s.uid = getuid();
00216 s.gid = getgid();
00217
00218 return md_32((char *) &s, sizeof(s));
00219 }
00220 #else
00221 uint32_t random32(int type)
00222 {
00223 char s[256];
00224 return md_32(s, sizeof(s));
00225 }
00226 #endif