Unabhängige Zufallszahlen / Random Klasse im .NET Framework

Heute hat mir ein Kollege erzählt, dass die Random Klasse im .NET Framework keine vernünftigen Zufallszahlen erzeugen würde und dass zwei Instanzen der Random Klasse jeweils die gleichen Zufallszahlen erzeugen. Das entsprechende Beispiel hat er mir schnell anhand eines kleinen NUnit-Tests gezeigt, der in etwa so aussah:

Lässt man das Programm laufen und vergleicht die beiden erzeugten Listen stellt man fest, dass beide Listen die gleichen Zufallszahlen enthalten, was meinen Kollegen etwas überrascht hat. Der Grund ist dafür aber eigentlich recht einfach und auch in der Hilfe zum .NET Framework dokumentiert. Die Initialisierung des Pseudozufallszahlengenerator wird anhand der Systemzeit durchgeführt und da die Random Klasse nur einen recht einfachen Zufallszahlengenerator beinhaltet, liefern beide Klassen jetzt die gleichen Werte zurück.
Das Problem kann man auf unterschiedlichen Wegen lösen. Zum Einen kann man einfach nur ein Objekt verwenden, das die Pseudozufallszahlen zurückliefert. Benötigt man trotzdem zwei unterschiedliche Instanzen der Klasse Random könnte man mittels System.Environment.TickCount die Klassen unterschiedlich instantiieren, bspw. so:

Eine letzte Möglichkeit ist es, einen Zufallszahlengenerator zu verwenden, der kryptographisch sichere Zufallszahlen erzeugt. So einen Zufallszahlengenerator bietet das .NET Framework unter System.Security.Cryptography.RandomNumberGenerator. Das Programm wird dadurch allerdings etwas aufwendiger, da ein solcher Zufallszahlengenerator immer in ein Byte-Array schreibt und man das Array dann erst in den benötigten Variablentyp umwandeln muss. Das Programm von oben würde unter Verwendung eines solchen Zufallszahlengenerator dann so aussehen:

Klingt doch eigentlich logisch, oder? Jedenfalls sollte man bei der Verwendung der Klasse Random etwas aufpassen und daran denken, dass bei Initialisierung mit gleichen Werten auch die gleichen Zufallszahlen zurückgegeben werden und sogar vorhersagbare Zufallszahlen zurückgeliefert werden (was in den meisten Fällen aber kein Problem sein sollte).

Inhalt eines Ordners mit einer ZIP Datei und MD5 prüfen

In den letzten Tagen habe ich mir die Frage gestellt, wie ich erkennen kann, ob die Dateien, die ich auf einem Server abgelegt habe, wirklich noch ihren richtigen Inhalt haben oder ob sie evtl. durch Übertragungsfehler o.ä. geändert wurden. Die übliche Methode ist, dass man bspw. den Inhalt einer ZIP Datei mit einem MD5 Hash abgleicht, aber das hilft bei einem Ordner dann auch nicht weiter. Aus diesem Grund habe ich mich mal daran gemacht und ein kleines Programm geschrieben, das zuerst die ZIP Datei mit einem MD5 Hash vergleicht und anschließend dann den Inhalt des ZIP Datei mit dem Inhalt des Ordners vergleicht und neben einer GUI auch per Kommandozeile gesteuert werden kann, damit man die Prüfung in einer Batch-Datei durchführen kann.

imageimageimage

Den Sourcecode und mehr Informationen gibt es auf GitHub. Eine kompilierte erste Version habe ich hier abgelegt: MD5ZipFolderCheck

ProjectEuler.NET – was zum Knobeln für Zwischendurch

Eigentlich wollte ich schon lange mal wieder etwas bloggen, genug Material hatte ich ja schon dafür, aber irgendwie hatte ich bisher noch keine Lust. Trotzdem will ich jetzt ein Projekt vorstellen, mit dem ich momentan viel Spaß habe: Project Euler. Project Euler lässt sich relativ einfach beschreiben: Es werden mathematische Aufgaben gestellt, die mit Hilfe einer frei wählbaren Programmiersprache (oder halt auch nur mit einem Zettel, wenn man das kann) gelöst werden sollen. Momentan werden 300 Probleme auf der Webseite bereitgestellt, die immer gleich abgearbeitet werden. Man bekommt eine Problembeschreibung und ein Beispiel. Anschließend kann man das Problem selbst Lösung und das gefundene Ergebnis auf der Webseite eintragen. Stimmt das Ergebnis wird ein PDF Dokument freigeschaltet, in dem die Lösung nochmal genau beschrieben wird. Hier kann man dann auch durchaus noch Verbesserungen für den eigenen gefundenen Algorithmus finden und seine Lösung entsprechend optimieren.
Die ersten paar Probleme habe ich bereits gelöst und mir ein für mich ausreichendes Framework in C# geschrieben, mit dem ich meine Lösungen recht einfach und komfortabel einbauen kann. Zusätzlich lege ich noch Wert auf Geschwindigkeit, weshalb ich die Geschwindigkeit meiner Lösungen messe und versuche sie zu optimieren.
Solltet ihr auch ein wenig Spaß an ein paar mathematischen Knobeleien haben, dann schaut einfach mal bei Project Euler vorbei. Es lohnt sich.

BufferedStream oder nicht?

Ab und an trifft man immer wieder auf elementare Fragen beim Programmieren, die man sich vorher in der Art noch nicht gestellt hat. Diesmal war es generell der FileStream in .NET. Die Frage ist halt, ob die FileStream Klasse in .NET schon einen Buffer verwendet oder ungebuffert ist, sodass man sie besser in einen BufferedStream einpackt, um die Performance zu erhöhen. Glücklicherweise bin ich auf einen Blogeintrag von Brad Abrams im MSDN gestossen, der diese Frage eindeutig beantwortet:

Bei einem FileStream kann im Konstruktor eine Buffergröße mitgegeben werden, d.h. dass ein FileStream generell gebuffert wird und man ihn somit nicht mehr extra in ein BufferedStream verpacken muss.

Tja, da man nicht reinschauen kann, war das nicht von vornherein klar, aber da das momentan für mich wichtig ist (ich brauche eine performante Schreibmethode für Daten), ist es nicht schlecht, wenn man das weiss und nicht unnötig Balast aufbaut.