static size_t g_spinpos = 0;
static char SPINNER[4] = { '/', '-', '\\', '|' };
-static uint8_t INDICES[ROW_LEN];
+static const uint8_t INDICES[UINT8_MAX + 1U] =
+{
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+ 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+ 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+ 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+ 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
+ 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
+};
//-----------------------------------------------------------------------------
// Utility Functions
#define TRACE(X, ...) __noop()
#endif
-static inline void swap(uint8_t *const row_buffer, const size_t a, const size_t b)
+static inline void swap(uint8_t *const row_buffer, const uint_fast8_t a, const uint_fast8_t b)
{
const uint8_t temp = row_buffer[a];
row_buffer[a] = row_buffer[b];
{
for (uint_fast8_t i = 0; i < ROW_LEN; ++i)
{
- const uint_fast8_t j = next_rand_range(rand, i+1U);
- if (j != i)
- {
- row_buffer[i] = row_buffer[j];
- }
+ const uint_fast8_t j = next_rand_range(rand, i + 1U);
+ row_buffer[i] = row_buffer[j];
row_buffer[j] = INDICES[i];
}
}
-static inline void swap_multiple_random(twister_t *const rand, uint8_t *const row_buffer, const size_t count)
+static inline void swap_multiple_random(twister_t *const rand, uint8_t *const row_buffer, const uint_fast8_t count)
{
- const size_t count_min = min(count, ROW_LEN / 2U);
bool map[ROW_LEN];
memset(&map[0], 0, sizeof(bool) * ROW_LEN);
- for (size_t i = 0U; i < count_min; ++i)
+ for (uint_fast8_t i = 0U; i < count; ++i)
{
- size_t a, b;
+ uint_fast8_t a, b;
do
{
a = next_rand_range(rand, ROW_LEN);
static inline void reverse_row(uint8_t *const row_buffer)
{
- size_t j = ROW_LEN - 1U;
- for (size_t i = 0U; i < ROW_LEN / 2U; ++i)
+ uint_fast8_t j = ROW_LEN - 1U;
+ for (uint_fast8_t i = 0U; i < ROW_LEN / 2U; ++i)
{
swap(row_buffer, i, j--);
}
}
-static inline uint32_t check_permutation(const size_t index, const uint8_t *const row_buffer, const uint32_t limit)
+static inline uint_fast8_t check_permutation(const uint_fast16_t index, const uint8_t *const row_buffer, const uint_fast8_t limit)
{
- uint32_t error = 0U;
- for (size_t i = 0; i < ROW_LEN; ++i)
+ uint_fast8_t error = 0U;
+ for (uint_fast8_t i = 0; i < ROW_LEN; ++i)
{
- if (row_buffer[i] == ((uint8_t)i))
+ if (row_buffer[i] == i)
{
error++;
}
}
if (error < limit)
{
- for (size_t i = 0; i < index; ++i)
+ for (uint_fast16_t i = 0; i < index; ++i)
{
- uint32_t distance = 0U;
- for (size_t j = 0; j < ROW_LEN; ++j)
+ uint_fast8_t distance = 0U;
+ for (uint_fast8_t j = 0; j < ROW_LEN; ++j)
{
if (g_table[i][j] != row_buffer[j])
{
}
if (distance < DISTANCE_MIN)
{
- if ((error = max_ui32(error, DISTANCE_MIN - distance)) >= limit)
+ if ((error = max_ui8(error, DISTANCE_MIN - distance)) >= limit)
{
break; /*early termination*/
}
static void print_row(const uint8_t *const row_buffer)
{
- for (size_t i = 0; i < ROW_LEN; ++i)
+ for (uint_fast8_t i = 0; i < ROW_LEN; ++i)
{
printf(i ? ",%02X" : "%02X", row_buffer[i]);
}
puts("");
}
-static inline void permutation_to_shuffle_indices(const uint8_t *const row_buffer, uint8_t *const indices_out)
-{
- uint8_t reference[ROW_LEN];
- for (uint32_t i = 0U; i < ROW_LEN; ++i)
- {
- reference[i] = ((uint8_t)i);
- }
- for (uint32_t i = 0U; i < ROW_LEN; ++i)
- {
- indices_out[i] = UINT8_MAX;
- for (uint32_t j = i; j < ROW_LEN; ++j)
- {
- if (reference[j] == row_buffer[i])
- {
- swap(&reference[0], i, j);
- indices_out[i] = ((uint8_t)j);
- break;
- }
- }
- }
- for (uint32_t i = 0; i < ROW_LEN; ++i)
- {
- if ((indices_out[i] == UINT8_MAX) || (reference[i] != row_buffer[i]))
- {
- puts("ERROR: Failed to derive shuffle indices!\n");
- }
- }
-}
-
static dump_table(FILE *out)
{
fprintf(out, "uint8_t MHASH_384_TABLE_MIX[%u][MHASH_384_LEN] =\n{\n", ROW_NUM);
- for (size_t i = 0; i < ROW_NUM; i++)
+ for (uint_fast16_t i = 0; i < ROW_NUM; i++)
{
fputs("\t{ ", out);
- for (size_t j = 0; j < ROW_LEN; j++)
+ for (uint_fast8_t j = 0; j < ROW_LEN; j++)
{
if (j > 0)
{
// Save / Load
//-----------------------------------------------------------------------------
-static bool save_table_data(const wchar_t *const filename, const size_t rows_completed_in)
+static bool save_table_data(const wchar_t *const filename, const uint_fast16_t rows_completed_in)
{
FILE *const file = _wfopen(filename, L"wb");
if (file)
}
}
-static bool load_table_data(const wchar_t *const filename, size_t *const rows_completed_out)
+static bool load_table_data(const wchar_t *const filename, uint_fast16_t *const rows_completed_out)
{
FILE *const file = _wfopen(filename, L"rb");
if (file)
success = false;
goto failed;
}
- for (size_t i = 0; i < rows_completed; ++i)
+ for (uint_fast16_t i = 0; i < rows_completed; ++i)
{
uint32_t checksum_expected;
if ((fread(&checksum_expected, sizeof(uint32_t), 1, file) != 1) || (fread(&g_table[i][0], sizeof(uint8_t), ROW_LEN, file) != ROW_LEN))
fclose(file);
if (success && rows_completed_out)
{
- *rows_completed_out = (size_t)rows_completed;
+ *rows_completed_out = (uint_fast16_t)rows_completed;
}
return success;
}
int wmain(int argc, wchar_t *argv[])
{
FILE *file_out = NULL;
- size_t initial_row_index = 0;
+ uint_fast16_t initial_row_index = 0;
char time_string[64];
printf("MHash GenTableMIX [%s]\n\n", __DATE__);
crit_exit("FATAL: Hash length must be a multiple of 32 bits!");
}
+ for (uint_fast8_t i = 0; i < ROW_LEN; ++i)
+ {
+ if (INDICES[i] != ((uint8_t)i))
+ {
+ crit_exit("FATAL: Invalid indices array detected!");
+ }
+ }
+
if (argc < 2)
{
printf("Table file not specified!\n\n");
bxmller_t bxmller;
gaussian_noise_init(&bxmller);
-
- for (uint_fast8_t i = 0; i < ROW_LEN; ++i)
- {
- INDICES[i] = ((uint8_t)i);
- }
-
+
if (_waccess(argv[1], 4) == 0)
{
printf("Loading existing table data and proceeding...\n");
}
}
- for (size_t i = initial_row_index; i < ROW_NUM; ++i)
+ for (uint_fast16_t i = initial_row_index; i < ROW_NUM; ++i)
{
printf("Row %03u of %03u [%c]", (uint32_t)(i + 1U), ROW_NUM, SPINNER[g_spinpos]);
uint8_t temp[ROW_LEN];
for (;;)
{
random_permutation(&rand, &g_table[i][0]);
- uint32_t error = check_permutation(i, &g_table[i][0], 2U * ROW_LEN);
- if (!(error > 0U))
- {
- goto success;
- }
- for (int_fast16_t retry = 0; retry < 4999; ++retry)
+ uint_fast8_t error = check_permutation(i, &g_table[i][0], 2U * ROW_LEN);
+ if (error > 0U)
{
- if (!((++counter) & 0x3))
- {
- printf("\b\b\b[%c]", SPINNER[g_spinpos]);
- g_spinpos = (g_spinpos + 1) % 4;
- }
- for (uint_fast16_t rand_init = 0U; rand_init < 9973U; ++rand_init)
+ static const int_fast16_t MAX_RETRY_RND = 9973, MAX_RETRY_RFN = 1499;
+ for (int_fast16_t retry = 0; retry < MAX_RETRY_RND; ++retry)
{
- random_permutation(&rand, &temp[0]);
- const uint32_t error_next = check_permutation(i, &temp[0], error);
- if (error_next < error)
+ if (!((++counter) & 0x3))
{
- TRACE("Improved by rand init!");
- retry = -1;
- memcpy(&g_table[i][0], &temp[0], sizeof(uint8_t) * ROW_LEN); /*keep*/
- if (!((error = error_next) > 0U))
- {
- goto success;
- }
+ TRACE("Randomize round %u of %u", retry, MAX_RETRY_RND);
+ printf("\b\b\b[%c]", SPINNER[g_spinpos]);
+ g_spinpos = (g_spinpos + 1) % 4;
}
- for (uint_fast8_t rotate = 0U; rotate < ROW_LEN; ++rotate)
+ for (uint_fast16_t rand_init = 0U; rand_init < 9973U; ++rand_init)
{
- rotate_row(&temp[0]);
- const uint32_t error_next = check_permutation(i, &temp[0], error);
+ random_permutation(&rand, &temp[0]);
+ const uint_fast8_t error_next = check_permutation(i, &temp[0], error);
if (error_next < error)
{
- TRACE("Improved by rotate!");
+ TRACE("Improved by rand init!");
retry = -1;
memcpy(&g_table[i][0], &temp[0], sizeof(uint8_t) * ROW_LEN); /*keep*/
if (!((error = error_next) > 0U))
goto success;
}
}
- reverse_row(&temp[0]);
- const uint32_t error_next_reverse = check_permutation(i, &temp[0], error);
- if (error_next_reverse < error)
+ for (uint_fast8_t rotate = 0U; rotate < ROW_LEN; ++rotate)
{
- TRACE("Improved by reverse!");
- retry = -1;
- memcpy(&g_table[i][0], &temp[0], sizeof(uint8_t) * ROW_LEN); /*keep*/
- if (!((error = error_next_reverse) > 0U))
+ rotate_row(&temp[0]);
+ const uint_fast8_t error_next = check_permutation(i, &temp[0], error);
+ if (error_next < error)
{
- goto success;
+ TRACE("Improved by rotate!");
+ retry = -1;
+ memcpy(&g_table[i][0], &temp[0], sizeof(uint8_t) * ROW_LEN); /*keep*/
+ if (!((error = error_next) > 0U))
+ {
+ goto success;
+ }
}
- }
- else
- {
reverse_row(&temp[0]);
+ const uint_fast8_t error_next_reverse = check_permutation(i, &temp[0], error);
+ if (error_next_reverse < error)
+ {
+ TRACE("Improved by reverse!");
+ retry = -1;
+ memcpy(&g_table[i][0], &temp[0], sizeof(uint8_t) * ROW_LEN); /*keep*/
+ if (!((error = error_next_reverse) > 0U))
+ {
+ goto success;
+ }
+ }
+ else
+ {
+ reverse_row(&temp[0]);
+ }
}
}
}
- }
- if (error > 0U)
- {
- static const int_fast16_t MAX_RETRY = 1201;
- for (int_fast16_t retry = 0; retry < MAX_RETRY; ++retry)
+ for (int_fast16_t retry = 0; retry < MAX_RETRY_RFN; ++retry)
{
- TRACE("Optimizer round %u of %u", retry, MAX_RETRY);
+ TRACE("Optimizer round %u of %u", retry, MAX_RETRY_RFN);
if (!retry)
{
rand_init(&rand, make_seed());
{
bool revert_1 = true;
swap(&g_table[i][0], swap_x1, swap_y1);
- const uint32_t error_next = check_permutation(i, &g_table[i][0], error);
+ const uint_fast8_t error_next = check_permutation(i, &g_table[i][0], error);
if (error_next < error)
{
TRACE("Improved by swap-1!");
{
bool revert_2 = true;
swap(&g_table[i][0], swap_x2, swap_y2);
- const uint32_t error_next = check_permutation(i, &g_table[i][0], error);
+ const uint_fast8_t error_next = check_permutation(i, &g_table[i][0], error);
if (error_next < error)
{
TRACE("Improved by swap-2!");
for (uint_fast8_t swap_y3 = swap_x3 + 1U; swap_y3 < ROW_LEN; ++swap_y3)
{
swap(&g_table[i][0], swap_x3, swap_y3);
- const uint32_t error_next = check_permutation(i, &g_table[i][0], error);
+ const uint_fast8_t error_next = check_permutation(i, &g_table[i][0], error);
if (error_next >= error)
{
swap(&g_table[i][0], swap_x3, swap_y3); /*revert*/
}
}
}
- const double sigma = 3.14159 * (1.0 + (retry / (double)MAX_RETRY));
+ const double sigma = 3.14159 * (1.0 + (retry / (double)MAX_RETRY_RFN));
for (int_fast16_t loop = 0; loop < 9973U; ++loop)
{
- const uint32_t swap_count = gaussian_noise_next(&rand, &bxmller, sigma, 4U, (ROW_LEN / 2U));
+ const uint_fast8_t swap_count = (uint_fast8_t)gaussian_noise_next(&rand, &bxmller, sigma, 4U, (ROW_LEN / 2U));
if (!((++counter) & 0x3FFF))
{
printf("\b\b\b[%c]", SPINNER[g_spinpos]);
{
memcpy(&temp[0], &g_table[i][0], sizeof(uint8_t) * ROW_LEN);
swap_multiple_random(&rand, &temp[0], swap_count);
- const uint32_t error_next = check_permutation(i, &temp[0], error);
+ const uint_fast8_t error_next = check_permutation(i, &temp[0], error);
if (error_next < error)
{
TRACE("Improved by swap-n (%u)!", swap_count);
}
}
}
+ TRACE("Restart!");
}
else
{