run.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include "hash/hash.h"
  2. #include "tap/tap.h"
  3. #include "hash/hash.c"
  4. #include <stdbool.h>
  5. #include <string.h>
  6. #define ARRAY_WORDS 5
  7. int main(int argc, char *argv[])
  8. {
  9. unsigned int i, j, k;
  10. uint32_t array[ARRAY_WORDS], val;
  11. char array2[sizeof(array) + sizeof(uint32_t)];
  12. uint32_t results[256];
  13. /* Initialize array. */
  14. for (i = 0; i < ARRAY_WORDS; i++)
  15. array[i] = i;
  16. plan_tests(53);
  17. /* hash_stable is guaranteed. */
  18. ok1(hash_stable(array, ARRAY_WORDS, 0) == 0x13305f8c);
  19. ok1(hash_stable(array, ARRAY_WORDS, 1) == 0x171abf74);
  20. ok1(hash_stable(array, ARRAY_WORDS, 2) == 0x7646fcc7);
  21. ok1(hash_stable(array, ARRAY_WORDS, 4) == 0xa758ed5);
  22. ok1(hash_stable(array, ARRAY_WORDS, 8) == 0x2dedc2e4);
  23. ok1(hash_stable(array, ARRAY_WORDS, 16) == 0x28e2076b);
  24. ok1(hash_stable(array, ARRAY_WORDS, 32) == 0xb73091c5);
  25. ok1(hash_stable(array, ARRAY_WORDS, 64) == 0x87daf5db);
  26. ok1(hash_stable(array, ARRAY_WORDS, 128) == 0xa16dfe20);
  27. ok1(hash_stable(array, ARRAY_WORDS, 256) == 0x300c63c3);
  28. ok1(hash_stable(array, ARRAY_WORDS, 512) == 0x255c91fc);
  29. ok1(hash_stable(array, ARRAY_WORDS, 1024) == 0x6357b26);
  30. ok1(hash_stable(array, ARRAY_WORDS, 2048) == 0x4bc5f339);
  31. ok1(hash_stable(array, ARRAY_WORDS, 4096) == 0x1301617c);
  32. ok1(hash_stable(array, ARRAY_WORDS, 8192) == 0x506792c9);
  33. ok1(hash_stable(array, ARRAY_WORDS, 16384) == 0xcd596705);
  34. ok1(hash_stable(array, ARRAY_WORDS, 32768) == 0xa8713cac);
  35. ok1(hash_stable(array, ARRAY_WORDS, 65536) == 0x94d9794);
  36. ok1(hash_stable(array, ARRAY_WORDS, 131072) == 0xac753e8);
  37. ok1(hash_stable(array, ARRAY_WORDS, 262144) == 0xcd8bdd20);
  38. ok1(hash_stable(array, ARRAY_WORDS, 524288) == 0xd44faf80);
  39. ok1(hash_stable(array, ARRAY_WORDS, 1048576) == 0x2547ccbe);
  40. ok1(hash_stable(array, ARRAY_WORDS, 2097152) == 0xbab06dbc);
  41. ok1(hash_stable(array, ARRAY_WORDS, 4194304) == 0xaac0e882);
  42. ok1(hash_stable(array, ARRAY_WORDS, 8388608) == 0x443f48d0);
  43. ok1(hash_stable(array, ARRAY_WORDS, 16777216) == 0xdff49fcc);
  44. ok1(hash_stable(array, ARRAY_WORDS, 33554432) == 0x9ce0fd65);
  45. ok1(hash_stable(array, ARRAY_WORDS, 67108864) == 0x9ddb1def);
  46. ok1(hash_stable(array, ARRAY_WORDS, 134217728) == 0x86096f25);
  47. ok1(hash_stable(array, ARRAY_WORDS, 268435456) == 0xe713b7b5);
  48. ok1(hash_stable(array, ARRAY_WORDS, 536870912) == 0x5baeffc5);
  49. ok1(hash_stable(array, ARRAY_WORDS, 1073741824) == 0xde874f52);
  50. ok1(hash_stable(array, ARRAY_WORDS, 2147483648U) == 0xeca13b4e);
  51. /* Hash should be the same, indep of memory alignment. */
  52. val = hash(array, sizeof(array), 0);
  53. for (i = 0; i < sizeof(uint32_t); i++) {
  54. memcpy(array2 + i, array, sizeof(array));
  55. ok(hash(array2 + i, sizeof(array), 0) != val,
  56. "hash matched at offset %i", i);
  57. }
  58. /* Hash of random values should have random distribution:
  59. * check one byte at a time. */
  60. for (i = 0; i < sizeof(uint32_t); i++) {
  61. unsigned int lowest = -1U, highest = 0;
  62. memset(results, 0, sizeof(results));
  63. for (j = 0; j < 256000; j++) {
  64. for (k = 0; k < ARRAY_WORDS; k++)
  65. array[k] = random();
  66. results[(hash(array, sizeof(array), 0) >> i*8)&0xFF]++;
  67. }
  68. for (j = 0; j < 256; j++) {
  69. if (results[j] < lowest)
  70. lowest = results[j];
  71. if (results[j] > highest)
  72. highest = results[j];
  73. }
  74. /* Expect within 20% */
  75. ok(lowest > 800, "Byte %i lowest %i", i, lowest);
  76. ok(highest < 1200, "Byte %i highest %i", i, highest);
  77. diag("Byte %i, range %u-%u", i, lowest, highest);
  78. }
  79. /* Hash of pointer values should also have random distribution. */
  80. for (i = 0; i < sizeof(uint32_t); i++) {
  81. unsigned int lowest = -1U, highest = 0;
  82. char *p = malloc(256000);
  83. memset(results, 0, sizeof(results));
  84. for (j = 0; j < 256000; j++)
  85. results[(hash_pointer(p + j, 0) >> i*8)&0xFF]++;
  86. free(p);
  87. for (j = 0; j < 256; j++) {
  88. if (results[j] < lowest)
  89. lowest = results[j];
  90. if (results[j] > highest)
  91. highest = results[j];
  92. }
  93. /* Expect within 20% */
  94. ok(lowest > 800, "hash_pointer byte %i lowest %i", i, lowest);
  95. ok(highest < 1200, "hash_pointer byte %i highest %i",
  96. i, highest);
  97. diag("hash_pointer byte %i, range %u-%u", i, lowest, highest);
  98. }
  99. return exit_status();
  100. }