Erzeugt zufälligen eindeutigen Code

8

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.

    
Achinth Gurkhi 05.05.2011, 06:18
quelle

13 Antworten

3

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.

    
Miguel Angelo 13.05.2011, 01:41
quelle
1

Muss es nur innerhalb des Prozesses eindeutig sein?

Gibt es irgendeinen Grund, einen Zähler, den Sie jedes Mal atomar erhöhen, nicht einfach zu behalten und ihn dann zurückzusetzen, wenn das Datum rollt?

    
Jon Skeet 05.05.2011 06:21
quelle
1

Ich würde

  1. Generieren Sie eine Reihe von eindeutigen Zufallszahlen zu Beginn eines jeden Tages bzw. vor jedem Tag in angemessener Zeit

  2. Nehmen Sie nacheinander jedes Mal eine Nummer aus dem Stapel, wenn Sie benötigt werden

Mr.Wizard 05.05.2011 10:08
quelle
1

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.

    
Jay 05.05.2011 06:27
quelle
1

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.

    
Alastair Pitts 05.05.2011 06:21
quelle
1

Sie KANN NICHT sicherstellen, dass Zufallszahlen nicht wiederholt werden. (Weil sie zufällig sind)

Ohne Vergleich mit bereits generierten Zahlen können Sie:

haben
  • Zufallszahl ODER
  • eindeutige Nummer.

Sie 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:

  • kombinieren Sie die Anzahl der Millisekunden und
  • atomarer Zähler (was bei jeder Generierung einer Zahl um Eins erhöht wird)

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.

    
jm666 11.05.2011 20:48
quelle
1

Wie wäre es mit einer modifizierten Version von Shuffle Bag ? So würde es funktionieren -

  1. vor dem Beginn des Tages, setzen Sie N eindeutige Zahlen, die Ihr Kriterium in einer Shuffle-Tasche
  2. erfüllen
  3. Im Laufe des Tages fordern Sie eine Nummer aus dem Shuffle Bag an.
  4. Shuffle bag gibt Ihnen eine zufällige Nummer aus der Tasche und verwirft sie - d. h., sie gibt nicht die gleiche Nummer zurück.
  5. am Ende des Tages würde es die Tasche bereinigen, bereit für den nächsten Tag.

Vorteile

  • Stellt sicher, dass die Nummer nicht wiederverwendet wird, ohne die vorhandene Liste zu überprüfen
  • Zahlen wären zufällig, ohne irgendeine Sequenz
  • Wende einfache Vernunftregeln an, um Shuffle Bag zu initialisieren, z. keine gemeinsamen / wiederholenden Sequenzen erlaubt (1111111 oder 123456789)
  • Einfach Shuffle Bag initialisieren - zufällige fortlaufende Nummern verwenden. d. h., beginnend mit der sechsstelligen Nummer, fügen Sie weiterhin eine kleine Zufallszahl hinzu, um den Beutel zu initialisieren.
  • Einfach, die Größe des Beutels basierend auf dem historischen Gebrauch zu ändern.
  • Sehr einfache Thread-sichere Implementierung in c #.

Ursprüngliche Quelle ist hier - die modifizierte Version könnte Ihrem Zweck dienen.

YetAnotherUser 13.05.2011 20:40
quelle
0

Fügen Sie am Ende des Codes eine Thread-ID an, um mit der Parallelität umzugehen.

    
Justin Simon 05.05.2011 06:23
quelle
0

Verwenden Sie Guid.NewGuid (), um etwas wie folgt zu erhalten:

0f8fad5b-d9cb-469f-a165-70867728950e

Dann werden Sie die '-'s los und konvertieren Sie die Buchstaben in ihre ASCII-Gegenstücke. (wo a = 97)

Dann in eine Zahl umwandeln.

    
tzup 05.05.2011 06:40
quelle
0

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.

    
Petr Abdulin 05.05.2011 07:13
quelle
0

Ich habe deine Idee fortgesetzt, die aktuelle Zeit zu verwenden, ich habe gerade Multi-Thread-Synchronisation hinzugefügt und benutze Zufallszahlen, um alle folgenden Zufallszahlen mit ihnen zu vergleichen, um Eindeutigkeit zu bieten.

%Vor%     
meir 11.05.2011 20:08
quelle
0

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 ...

    
TryCatch 12.05.2011 05:18
quelle
0

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 )% M. Dies erzeugt eine Sequenz von X n mit der Periode M, d. H. Die Sequenz erzeugt alle Zahlen in [0..999999999] genau einmal, bevor sie mit der Wiederholung beginnt.

    
Strawberry Donut 12.05.2011 06:55
quelle

Tags und Links