Jeśli można, używamy ziarna z /dev/urandom.
authorMichał Bartoszkiewicz <mbartoszkiewicz@gmail.com>
Mon, 21 Dec 2009 23:49:13 +0000 (00:49 +0100)
committerMichał Bartoszkiewicz <mbartoszkiewicz@gmail.com>
Mon, 21 Dec 2009 23:49:13 +0000 (00:49 +0100)
Ziarno generowane przy pomocy time() zmienia się tylko raz na sekundę,
przez co wszystkie choinki generowane w tej samej sekundzie wyglądały
identycznie.
Jeżeli nie uda się użyć ziarna z /dev/urandom używamy ziarna z time().

choinka.c

index 1e296140954d1971888b15393713ba0925aa8e15..b10f073e25bcfa9df85a303995af0708041d4b9c 100644 (file)
--- a/choinka.c
+++ b/choinka.c
@@ -24,6 +24,23 @@ atrybut const podstawa = {0, COLOR_YELLOW};
 atrybut const podpis = {A_BOLD, COLOR_RED};
 atrybut const gwiazdka = {A_BOLD, COLOR_YELLOW};
 
+void inicjuj_rng()
+{
+  unsigned ziarno = 0;
+  FILE* f = fopen("/dev/urandom", "rb");
+  if (f != NULL) {
+    unsigned nowe_ziarno;
+    if (fread(&nowe_ziarno, sizeof nowe_ziarno, 1, f) == 1) {
+      ziarno = nowe_ziarno;
+    }
+    fclose(f);
+  }
+  if (ziarno == 0) {
+    ziarno = time(NULL);
+  }
+  srand(ziarno);
+}
+
 char const rysunek[] =
 "           *\n"
 "          /.\\\n"
@@ -50,7 +67,7 @@ void ustaw(atrybut const* attr)
 
 int main()
 {
-  srand(time(NULL));
+  inicjuj_rng();
   setupterm(NULL, 1, NULL);
   atrybut const* kolor = &choinka;
   for (int i = 0; rysunek[i] != '\0'; i++) {