/* * common functions for (parallel) cellular automaton * * (c) 2016 Steffen Christgau * * configuration initialization based on * (c) 1996,1997 Peter Sanders, Ingo Boesnach * */ #include <stdint.h> #include <stdlib.h> #include <stdio.h> #include <assert.h> #include "openssl/md5.h" #include "openssl/evp.h" #include "ca_common.h" void ca_init(int argc, char** argv, int *lines, int *its) { assert(argc == 3); *lines = atoi(argv[1]); *its = atoi(argv[2]); assert(*lines > 0); } /* random starting configuration */ void ca_init_config(line_t *buf, int lines, int skip_lines) { volatile int scratch; srand(424243); /* let the RNG spin for some rounds (used for distributed initialization) */ for (int y = 1; y <= skip_lines; y++) { for (int x = 1; x <= XSIZE; x++) { scratch = scratch + (rand() % 2); } } for (int y = 1; y <= lines; y++) { for (int x = 1; x <= XSIZE; x++) { buf[y][x] = rand() % 2; } } } static char* ca_buffer_to_hex_str(const uint8_t* buf, size_t buf_size) { char *retval, *ptr; retval = ptr = calloc(MD5_DIGEST_LENGTH * 2 + 1, sizeof(*retval)); for (size_t i = 0; i < MD5_DIGEST_LENGTH; i++) { snprintf(ptr, 3, "%02X", buf[i]); ptr += 2; } return retval; } static void ca_print_hash_and_time(const char *hash, const double time) { printf("hash: %s\ttime: %.3f s\n", (hash ? hash : "ERROR"), time); } static void ca_clean_ghost_zones(line_t *buf, int lines) { for (int y = 0; y < lines; y++) { buf[y][0] = 0; buf[y][XSIZE + 1] = 0; } } void ca_hash_and_report(line_t *buf, int lines, double time_in_s) { uint8_t hash[MD5_DIGEST_LENGTH]; uint32_t md_len; EVP_MD_CTX *ctx = EVP_MD_CTX_new(); EVP_DigestInit_ex(ctx, EVP_md5(), NULL); ca_clean_ghost_zones(buf, lines); EVP_DigestUpdate(ctx, buf, lines * sizeof(*buf)); EVP_DigestFinal_ex(ctx, hash, &md_len); char* hash_str = ca_buffer_to_hex_str(hash, MD5_DIGEST_LENGTH); ca_print_hash_and_time(hash_str, time_in_s); free(hash_str); EVP_MD_CTX_free(ctx); }