1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdio.h> 3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdlib.h> 4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <assert.h> 5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef signed int Int; 7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef unsigned int UInt; 8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef unsigned long long int Addr64; 9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef unsigned char UChar; 10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef unsigned long int UWord; 11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic inline UInt ROL32 ( UInt x, UInt n ) { 13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(n != 0); 14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov n &= 31; 15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov x = (x << n) | (x >> (32-n)); 16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return x; 17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov////////////////////////////////////////////////////////// 20b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 21b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef 22b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct { 23b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Addr64 ga; 24b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int nbytes; 25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar* bytes; 26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar* actual; 27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov GuestBytes; 29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovGuestBytes* read_one ( FILE* f ) 31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int r; 33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt i; 34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt esum, csum; 35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov GuestBytes* gb = malloc(sizeof(GuestBytes)); 37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(gb); 38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (feof(f)) return NULL; 40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(!ferror(f)); 41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r= fscanf(f, "GuestBytes %llx %d ", &gb->ga, &gb->nbytes); 43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0) printf("r = %d\n", r); 44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(r == 2); 45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(gb->ga != 0); 47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(gb->nbytes > 0); 48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(gb->nbytes < 5000); // let's say 49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int nToAlloc = gb->nbytes + (gb->ga & 3); 51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov gb->bytes = malloc( gb->nbytes + nToAlloc); 53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov gb->actual = gb->bytes + (gb->ga & 3); 54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(gb->bytes); 55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov csum = 0; 57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < gb->nbytes; i++) { 58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt b; 59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r= fscanf(f, "%02x ", &b); 60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(r == 1); 61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov gb->actual[i] = b; 62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov csum = (csum << 1) ^ b; 63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r= fscanf(f, " %08x\n", &esum); 66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(r == 1); 67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(esum == csum); 69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return gb; 71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov////////////////////////////////////////////////////////// 74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid apply_to_all ( FILE* f, 76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void(*fn)( GuestBytes*, void* ), 77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* opaque ) 78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (!feof(f)) { 80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov GuestBytes* gb = read_one(f); 81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0) printf("got %llu %d\n", gb->ga, gb->nbytes); 82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fn( gb, opaque ); 83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov free(gb->bytes); 84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov free(gb); 85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov////////////////////////////////////////////////////////// 89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt hash_const_zero ( GuestBytes* gb ) { 91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt hash_sum ( GuestBytes* gb ) { 95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt i, sum = 0; 96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < gb->nbytes; i++) 97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sum += (UInt)gb->actual[i]; 98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return sum; 99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt hash_rol ( GuestBytes* gb ) { 102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt i, sum = 0; 103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < gb->nbytes; i++) { 104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sum ^= (UInt)gb->actual[i]; 105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sum = ROL32(sum,7); 106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return sum; 108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt cand0 ( GuestBytes* gb ) 111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UWord addr = (UWord)gb->actual; 113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UWord len = gb->nbytes; 114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt sum = 0; 115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* pull up to 4-alignment */ 116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while ((addr & 3) != 0 && len >= 1) { 117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar* p = (UChar*)addr; 118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sum = (sum << 8) | (UInt)p[0]; 119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addr++; 120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov len--; 121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* vectorised + unrolled */ 123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (len >= 16) { 124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt* p = (UInt*)addr; 125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sum = ROL32(sum ^ p[0], 13); 126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sum = ROL32(sum ^ p[1], 13); 127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sum = ROL32(sum ^ p[2], 13); 128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sum = ROL32(sum ^ p[3], 13); 129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addr += 16; 130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov len -= 16; 131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* vectorised fixup */ 133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (len >= 4) { 134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt* p = (UInt*)addr; 135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sum = ROL32(sum ^ p[0], 13); 136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addr += 4; 137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov len -= 4; 138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* scalar fixup */ 140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (len >= 1) { 141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar* p = (UChar*)addr; 142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sum = ROL32(sum ^ (UInt)p[0], 19); 143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addr++; 144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov len--; 145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return sum; 147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt cand1 ( GuestBytes* gb ) 150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UWord addr = (UWord)gb->actual; 152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UWord len = gb->nbytes; 153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt sum1 = 0, sum2 = 0; 154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* pull up to 4-alignment */ 155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while ((addr & 3) != 0 && len >= 1) { 156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar* p = (UChar*)addr; 157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sum1 = (sum1 << 8) | (UInt)p[0]; 158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addr++; 159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov len--; 160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* vectorised + unrolled */ 162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (len >= 16) { 163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt* p = (UInt*)addr; 164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt w; 165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w = p[0]; sum1 = ROL32(sum1 ^ w, 31); sum2 += w; 166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w = p[1]; sum1 = ROL32(sum1 ^ w, 31); sum2 += w; 167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w = p[2]; sum1 = ROL32(sum1 ^ w, 31); sum2 += w; 168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w = p[3]; sum1 = ROL32(sum1 ^ w, 31); sum2 += w; 169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addr += 16; 170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov len -= 16; 171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sum1 ^= sum2; 172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* vectorised fixup */ 174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (len >= 4) { 175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt* p = (UInt*)addr; 176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt w = p[0]; 177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sum1 = ROL32(sum1 ^ w, 31); sum2 += w; 178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addr += 4; 179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov len -= 4; 180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sum1 ^= sum2; 181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* scalar fixup */ 183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (len >= 1) { 184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar* p = (UChar*)addr; 185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt w = (UInt)p[0]; 186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sum1 = ROL32(sum1 ^ w, 31); sum2 += w; 187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov addr++; 188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov len--; 189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return sum1 + sum2; 191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt adler32 ( GuestBytes* gb ) 194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UWord addr = (UWord)gb->actual; 196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UWord len = gb->nbytes; 197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt s1 = 1; 198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt s2 = 0; 199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar* buf = (UChar*)addr; 200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (len >= 4) { 201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s1 += buf[0]; 202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s2 += s1; 203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s1 += buf[1]; 204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s2 += s1; 205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s1 += buf[2]; 206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s2 += s1; 207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s1 += buf[3]; 208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s2 += s1; 209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov buf += 4; 210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov len -= 4; 211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (len > 0) { 213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s1 += buf[0]; 214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s2 += s1; 215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov len--; 216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov buf++; 217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return (s2 << 16) + s1; 219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov////////////////////////////////////////////////////////// 225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt (*theFn)(GuestBytes*) = 227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //hash_const_zero; 228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //hash_sum; 229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov//hash_rol; 230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov//cand0; 231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov cand1; 232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //adler32; 233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovInt cmp_UInt_ps ( UInt* p1, UInt* p2 ) { 235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (*p1 < *p2) return -1; 236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (*p1 > *p2) return 1; 237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovInt nSetBits ( UInt w ) 241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int i, j; 243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov j = 0; 244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < 32; i++) 245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (w & (1<<i)) 246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov j++; 247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return j; 248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovInt toc_nblocks = 0; 251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovInt toc_nblocks_with_zero = 0; 252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovdouble toc_sum_of_avgs = 0.0; 253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid invertBit ( UChar* b, UInt ix, UInt bix ) { 255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov b[ix] ^= (1 << bix); 256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid try_onebit_changes( GuestBytes* gb, void* opaque ) 259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov toc_nblocks++; 261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* collect up the hash values for all one bit changes of the key, 262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov and also that for the unmodified key. Then compute the number 263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov of changed bits for all of them. */ 264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt hashIx = 0; 265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt nHashes = 8 * gb->nbytes; 266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt* hashes = malloc( nHashes * sizeof(UInt) ); 267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt byteIx, bitIx; 269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt hInit, hFinal, hRunning; 270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int dist, totDist = 0, nNoDist = 0; 271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(hashes); 272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov hInit = theFn( gb ); 273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (byteIx = 0; byteIx < gb->nbytes; byteIx++) { 274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (bitIx = 0; bitIx < 8; bitIx++) { 275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov invertBit(gb->actual, byteIx, bitIx); 277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //invertBit(gb->actual, byteIx, bitIx ^ 4); 278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov hRunning = theFn( gb ); 280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov dist = nSetBits(hRunning ^ hInit); 282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov totDist += dist; 283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (dist == 0) nNoDist++; 284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov hashes[hashIx++] = hRunning; 286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov invertBit(gb->actual, byteIx, bitIx); 288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //invertBit(gb->actual, byteIx, bitIx ^ 4); 289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0) printf(" %02d.%d %08x %d\n", 291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov byteIx, bitIx, hRunning ^ hInit, dist); 292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 294b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov hFinal = theFn( gb ); 295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(hFinal == hInit); 296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(hashIx == nHashes); 297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 298b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (nNoDist > 0) 299b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%4d measurements, %5.2f avg dist, %2d zeroes\n", 300b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (Int)nHashes, (double)totDist / (double)nHashes, nNoDist); 301b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else 302b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%4d measurements, %5.2f avg dist\n", 303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (Int)nHashes, (double)totDist / (double)nHashes); 304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 305b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (nNoDist > 0) 306b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov toc_nblocks_with_zero++; 307b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov toc_sum_of_avgs += (double)totDist / (double)nHashes; 309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov free(hashes); 311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov////////////////////////////////////////////////////////// 314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint main ( void ) 316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov FILE* f = stdin; 318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov apply_to_all(f, try_onebit_changes, NULL); 319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("\n%d blocks, %d with a zero, %5.2f avg avg\n\n", 320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov toc_nblocks, toc_nblocks_with_zero, toc_sum_of_avgs / (double)toc_nblocks ); 321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov////////////////////////////////////////////////////////// 325