-
Dorian Stoll authoredDorian Stoll authored
ca_common.c 1.97 KiB
/*
* 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);
}