Was ist ein Pseudozufallszahlengenerator?
Was Anian Anian unten schreibt ist eine prima Erklärung wie ein Pseudozufallszahlengenerator funktioniert.
Und hier wäre noch eine konkrete Art, wie man so einen Algorithmus in C implementieren könnte.
#import <inttypes.h> 
 /* Der aktuelle Wert des Zufallsgenerators */ 
uint32_t randSeed = 0xaffecafe;  
 /*! 
 * \brief Pseudo random number generator that returns  
 * the next number from a current seed value that looks random. 
 * \return The next Pseudo randdom number based on  
 *         the value of \p randSeed. 
 */ 
uint32_t pseudoRand() 
{ 
    const uint32_t a = randSeed; 
     randSeed ^= a >> 8; 
    randSeed ^= a << 4; 
    randSeed ^= 0xfeedface; // bring in some "noise" 
    randSeed ^= a << ((a>>3) & 0xf); 
    randSeed ^= a << ((a<<8) & 0x7); 
    return randSeed; 
} 
Wenn man den nun auf die ersten 10 Zahlen anwendet und dabei nur die untersten 8 bits ausmaskiert (also auf einen Wertebereich von 0…255 einschränkt)…
for (unsigned int i=0; i != 10; ++i) 
{ 
    printf("pseudoRand = %u\n", pseudoRand() & 0xff); 
} 
…dann ergibt das:
pseudoRand = 198 
pseudoRand = 209 
pseudoRand = 54 
pseudoRand = 74 
pseudoRand = 34 
pseudoRand = 251 
pseudoRand = 69 
pseudoRand = 241 
pseudoRand = 40 
pseudoRand = 230 
Interessant ist, dass diese Zahlenfolge zufällig aussieht, aber eigentlich aus sich selbst errechnet ist - also selbstähnlich ist.
Desweiteren kann man nun diese scheinbare (=pseudo) Zufallsfolge von Zahlen exakt wieder reproduzieren kann, indem man den Seed wieder auf den Eingangs eingestellten Wert - also hier 0xaffecafe - setzt.
Last not least wird diese Zahlensequenz auch auf jedem Prozessor so generiert werden. Es spielt also keine Rolle, ob das ein 8-, 16- oder 32 Bit Prozessor ist. ferner ist es unerheblich ob die Architektur vom Typ Big- oder Little Endian ist!
Diese Aspekte können eine Rolle spielen, falls man einen Algorithmus entwerfen möchte, der reproduzierbare Zufallszahlen erzeugen kann und dieser diversen Prozessorarchitekturen die selbe Sequenz liefern soll.
Oben gezeigter Algorithmus ist aber freilich nur ein Beispiel von Vielen. Man kann freilich die Bits noch viel wilder durchschütteln als ich es oben gezeigt habe. Dadurch erreicht man eine noch höhere Entropie (Zufallsverteilung über den gegebenen Zahlenraum).
Es geht mir nur darum, dass verstanden wird, wie das eigentlich funktioniert.
Noch eine Bemerkung am Rande:
Pseudozufallszahlen - also solche, die zufällig aussehen, aber exakt reproduzierbar sind - kann man z-B. auch prima zum Testen von Speichern verwenden. Wenn es darum geht, den Speicher mit Zufallsdaten zu füllen um diese dann wieder auszulesen / verifizieren. Knn man das schön mit einem solchen Pseudozufallsgenerator machen. Einfach mit einem bekannten Seed anfangen Zufallszahlen in den Speicher schreiben und dann beim Verification run wieder beim start-Seed anfangen und prüfen, ob dann da das selbe "Zufallsbyte" drin steht wie es ursprünglich geschrieben wurde.
static void _fillDramRandom(size_t longCount) 
{ 
 // Set the Random Generator to defined start point  
 randSeed = 0xdeadbeef;  
   volatile uint32_t* dramMemoryAddressPtr = <START AUF DRAM>; 
 for(;longCount;--longCount, ++dramMemoryAddressPtr) 
 { 
  *dramMemoryAddressPtr = pseudoRand(); 
 } 
} 
 static bool _verifyDramRandom(size_t longCount) 
{ 
 bool success = true; // Be optimistic 
  // (Re)Set the Random Generator to defined start point  
 randSeed = 0xdeadbeef;  
   volatile const uint32_t* dramMemoryAddressPtr = <START AUF DRAM>; 
 for(;longCount;--longCount, ++dramMemoryAddressPtr) 
 { 
  if (*dramMemoryAddressPtr != pseudoRand()) 
  { 
   success = false; 
   printf("Memory Compare failed at address %p\n", 
    dramMemoryAddressPtr); 
   break; 
  } 
 } 
 return success; 
} 
 static void _testMemory(size_t longCount) 
{ 
 _fillDramRandom(longCount); 
 assert(false == _verifyDramRandom(longCount)); 
} 