Ich muss einen neunstelligen numerischen Code generieren (zufällig, vorzugsweise), der für einen bestimmten Tag einzigartig ist (die gleiche Nummer kann nicht am selben Tag erneut generiert werden). Ich dachte daran, HHMMSSmmm (Stunden, Minuten, Sekunden und Millisekunden) zu verwenden, um den eindeutigen Code zu erzeugen, ist aber nicht wirklich zufällig. Auf diese Codegenerierungsmethode kann mit mehreren Methoden gleichzeitig zugegriffen werden, so dass ich die Methode sperren muss. Aber stellt dies sicher, dass die Nummer eindeutig ist, da es möglich ist, dass die Generierung der Nummer weniger als eine Millisekunde dauert und zwei Threads die gleiche Nummer bekommen?
Gibt es eine bessere Möglichkeit, einen zufälligen eindeutigen numerischen Code zu generieren, der für einen bestimmten Tag einzigartig ist? Die Anzahl der Ziffern kann zwischen 6 und 9 Ziffern betragen.
Bearbeiten: Die Anzahl der zu generierenden Zufallszahlen hängt von der Anzahl der Transaktionen ab. Anfänglich könnte die Anzahl niedriger sein, aber im Laufe der Zeit kann sie sehr hoch werden (mehrere Transaktionen pro Sekunde). Daher möchte ich die Nummer nicht mit einer gebrauchten Liste vergleichen, da dies Leistungsprobleme haben könnte.
Zufälligkeit ist erforderlich, da diese Nummer vom Benutzer am Telefon eingegeben wird. Diese Nummer ist die einzige Möglichkeit, die Online-Transaktion mit der Telefontransaktion zu verknüpfen, damit der Benutzer nicht versehentlich eine andere Nummer eingeben muss.
Die Generierung von Zufallszahlen muss in einer ASP.NET MVC-Anwendung stattfinden.
Wenn Sie von einer Zufallszahl mit 6 Ziffern ausgehen, dann addieren Sie zufällige, aber klein genug Zahlen, Sie können das vielleicht tun. Sie können das Dateisystem als Sperrspeicher verwenden, wenn Sie möchten ... aber ich denke, Sie sollten eine DB für die Produktion verwenden!
Hier ist das Beispiel von dem, worüber ich spreche:
Dieses Beispiel ist eine Konsolenanwendung, die eine Datei zum Steuern der Parallelität und zum Speichern der zuletzt verwendeten Nummer und des Datums verwendet, an dem sie generiert wurde.
Wenn Sie es mehrmals ausführen, werden Sie sehen, was passiert. Beide haben ihre eigenen eindeutigen Nummern.
Es speichert NICHT alle generierten Zahlen , wie Sie es benötigen!
Dieses Beispiel kann ungefähr 999000 Zufallszahlen pro Tag im Bereich von 6 und 9 Ziffern enthalten. Das sind ungefähr 11 Zahlen pro Sekunde.
%Vor%Ich denke, dass dies Ihre Anforderungen erfüllt ... liege ich falsch?
Wenn ich es bin, sag es einfach und ich werde versuchen, mehr zu helfen.
Wenn alle Aufrufe innerhalb der gleichen JVM sind, denke ich, dass Sie nur eine statische erstellen müssen, um die letzte zugewiesene Nummer zu speichern, eine einzelne Funktion schreiben, um die Zahl zu erhöhen, den neuen Wert zurückzugeben und dann zu synchronisieren es. Wie:
%Vor%Wenn mehrere JVMs vorhanden sind, ist es am einfachsten, die Nummer in einer Datenbank zu speichern und die Datenbanksperrung zu verwenden, um die Nummern eindeutig zu halten.
Aktualisieren
Ich sehe, Sie haben eine Anforderung hinzugefügt, dass die Zahlen zufällig sind. Wenn Sie möchten, dass die Zahlen zufällig UND eindeutig sind, sehe ich keine Alternative zu einer Liste aller zuvor zugewiesenen Nummern. Sie können sie in einer Art Hash-Tabelle speichern, so dass Sie nicht jedes Mal die gesamte Liste durchsuchen müssen. Wenn Sie viele davon zuweisen, kann die Größe der Hash-Tabelle ein Problem sein, auch wenn Sie sie nicht sequentiell durchsuchen müssen.
Je nachdem, was Sie erreichen möchten, könnten Sie ein Schema entwickeln, das Zahlen nicht sequenziell, sondern in einer starren Reihenfolge zuweist, sodass sie für einige Zwecke zufällig erscheinen. Zum Beispiel könnten Sie um eine Zahl erhöhen, die sehr groß in Bezug auf das Maximum und relativ Primzahl mit dem Maximum ist, und dann jedes Mal, wenn das nächste Inkrement übergehen würde, das Maximum subtrahieren. Um es zu verkleinern, nehmen Sie an, dass Sie 2-stellige statt 9-stellige Zahlen zugewiesen haben. Inkrementieren um 37. Dann würden Sie 37, 74, 111 Wraps zu 11, 48, 85, 122 Wraps zu 22 usw. zuweisen.
BEARBEITEN: Diese Antwort macht keinen Sinn, wenn ich die Notwendigkeit erkannte, mehrere eindeutige Codes pro Tag zu haben, die aber am nächsten Tag wiederholt werden können. Wenn Sie nach einem einzigen eindeutigen Code pro Tag suchen (aus welchem Grund auch immer), dann ist diese Antwort nützlich:)
Wenn der Code nur einmal pro Tag eindeutig sein soll, dann verwenden Sie einfach das Datum als Code ...
vielleicht YYYYmmdd, was dir (für das heutige Datum) 20110505 geben würde, und morgen wäre 20110506.
Sie KANN NICHT sicherstellen, dass Zufallszahlen nicht wiederholt werden. (Weil sie zufällig sind)
Ohne Vergleich mit bereits generierten Zahlen können Sie:
habenSie benötigen eine eindeutige Nummer mit einem zufälligen Aussehen. Wenn die Millisekunden vom Anfang des Tages nicht genügend zufällig aussehen, kombinieren Sie es mit einer anderen eindeutigen Nummer.
Zum Beispiel:
Wenn Sie sie beispielsweise summieren, können Sie Folgendes generieren: 999999999-86400000 = 913599999 eindeutige Zahlen pro Tag.
Obwohl sie nicht zufällig sind, werden sie einzigartig sein - und nur um 00:00 vorhersehbar.
Hier sind Variationen dafür, zum Beispiel das Zurücksetzen des Zählers um 00:00 nicht.
Wie wäre es mit einer modifizierten Version von Shuffle Bag ? So würde es funktionieren -
Vorteile
Ursprüngliche Quelle ist hier - die modifizierte Version könnte Ihrem Zweck dienen.
Fügen Sie am Ende des Codes eine Thread-ID an, um mit der Parallelität umzugehen.
Der geeignete Code-Generator hängt davon ab, wie viele Zahlen im Zeitraum generiert werden sollen. Betrachten Sie folgende Muster:
HHMMSS + NNN- gibt Ihnen Platz für 999 Zufallszahlen in einer Sekunde.
HH + NNNNNNN - gibt Ihnen Platz für 9999999 Zufallszahlen in einer Stunde. Etc.
Wenn die Zeitverteilung der Nummerngenerierungsmethode einheitlich ist, ist jedes Muster fast gleich.
Wie auch immer, unter Berücksichtigung der Beschränkung der Zufallszahlenlänge gibt es immer eine Grenze für die Anzahl der Methodenaufrufe, bevor Konflikte auftreten. Z.B. Wenn die Methode aufgerufen wird & gt; 1000 Mal pro Sekunde.
public double GetRandomNumber() {object operation = new object(); lock(operation) { return new Random().NextDouble(); } }
würde tun.
Dies hängt nicht vom Tag / der Zeit ab, daher ist es noch zufälliger als Ihre Anforderung. Jetzt die Tatsache, dass die Zahl weniger als 1 ist, überlasse ich Ihnen als Übung ...
Auch, wenn Sie die Anzahl der für einen bestimmten Tag generierten Zahl verfolgen möchten - behalten Sie eine Liste von ihnen und regenerieren, wenn Duplikat generiert wird. Aber das werde ich nicht für dich schreiben, da du der Programmierer in deiner Situation bist ...
Je nachdem, wie viel Zufälligkeit erforderlich ist, kann ein linearer Kongruenzgenerator mit den entsprechenden Parametern das sein, was Sie suchen zum. Wenn Sie zum Beispiel den Richtlinien des Wikipedia-Eintrags über die Periodenlänge folgen, können Sie folgende Parameter verwenden: M = 1000000000, a = 21, c = 3, dann verwenden Sie einen beliebigen Anfangswert X 0 in [0..999999999], und berechne X n + 1 <(a * Xn