#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <zlib.h> #include <openssl/md2.h> #include <openssl/md4.h> #include <openssl/md5.h> const unsigned int prime = 2000000011; unsigned int karprabin (unsigned char *datac, int N) { assert(N%4==0); unsigned int *data=(unsigned int*)datac; N=N/4; int i; unsigned int result=0; for (i=0; i<N; i++) { result=(result*prime)+data[i]; } return result; } // According to // P. L'Ecuyer, "Tables of Linear Congruential Generators of // Different Sizes and Good Lattice Structure", Mathematics of // Computation 68:225, 249--260 (1999). // m=2^{32}-5 a=1588635695 is good. const unsigned int mkr = 4294967291U; const unsigned int akr = 1588635695U; // But this is slower unsigned int karprabinP (unsigned char *datac, int N) { assert(N%4==0); unsigned int *data=(unsigned int*)datac; N=N/4; int i; unsigned long long result=0; for (i=0; i<N; i++) { result=((result*akr)+data[i])%mkr; } return result; } float tdiff (struct timeval *start, struct timeval *end) { return (end->tv_sec-start->tv_sec) +1e-6*(end->tv_usec - start->tv_usec); } int main (int argc __attribute__((__unused__)), char *argv[] __attribute__((__unused__))) { struct timeval start, end; const int N=2<<20; unsigned char *data=malloc(N); int i; assert(data); for (i=0; i<N; i++) data[i]=random(); // adler32 { uLong a32 = adler32(0L, Z_NULL, 0); for (i=0; i<3; i++) { gettimeofday(&start, 0); a32 = adler32(a32, data, N); gettimeofday(&end, 0); float tm = tdiff(&start, &end); printf("adler32=%lu, time=%9.6fs %9.6fns/b\n", a32, tm, 1e9*tm/N); } } // crc32 { uLong c32 = crc32(0L, Z_NULL, 0); for (i=0; i<3; i++) { gettimeofday(&start, 0); c32 = crc32(c32, data, N); gettimeofday(&end, 0); float tm = tdiff(&start, &end); printf("crc32=%lu, time=%9.6fs %9.6fns/b\n", c32, tm, 1e9*tm/N); } } // MD2 { unsigned char buf[MD2_DIGEST_LENGTH]; int j; for (i=0; i<3; i++) { gettimeofday(&start, 0); MD2(data, N, buf); gettimeofday(&end, 0); float tm = tdiff(&start, &end); printf("md2="); for (j=0; j<MD2_DIGEST_LENGTH; j++) { printf("%02x", buf[j]); } printf(" time=%9.6fs %9.6fns/b\n", tm, 1e9*tm/N); } } // MD4 { unsigned char buf[MD4_DIGEST_LENGTH]; int j; for (i=0; i<3; i++) { gettimeofday(&start, 0); MD4(data, N, buf); gettimeofday(&end, 0); float tm = tdiff(&start, &end); printf("md4="); for (j=0; j<MD4_DIGEST_LENGTH; j++) { printf("%02x", buf[j]); } printf(" time=%9.6fs %9.6fns/b\n", tm, 1e9*tm/N); } } // MD5 { unsigned char buf[MD5_DIGEST_LENGTH]; int j; for (i=0; i<3; i++) { gettimeofday(&start, 0); MD5(data, N, buf); gettimeofday(&end, 0); float tm = tdiff(&start, &end); printf("md5="); for (j=0; j<MD5_DIGEST_LENGTH; j++) { printf("%02x", buf[j]); } printf(" time=%9.6fs %9.6fns/b\n", tm, 1e9*tm/N); } } // karp rabin { for (i=0; i<3; i++) { gettimeofday(&start, 0); unsigned int kr = karprabin(data, N); gettimeofday(&end, 0); float tm = tdiff(&start, &end); printf("kr=%ud time=%9.6fs %9.6fns/b\n", kr, tm, 1e9*tm/N); } } free(data); return 0; }