Frage

wollte ich eine Zahl, die für einen Tag (24 Stunden) einzigartig bleiben. Im Folgenden ist der Code, den ich kam mit; Ich habe mich gefragt, um seine Täuschungen / mögliche Risiken; ‚Ich glaube,‘ dies garantiert eine 12-stellige eindeutige Nummer für einen Tag atleast.

Die Logik ist das aktuelle Datum / Zeit (hhmmssmmm) und verketten die ersten vier Bytes der Abfrageleistung Zähler Ergebnis zu erhalten.

__forceinline bool GetUniqueID(char caUID[MAX_STRING_LENGTH])
{
    //Logic: Add HHMMSSmmm with mid 3 bytes of performance counter.
    //Guarantees that in a single milli second band (0 to 999) the three bytes 
    //of performance counter would always be unique.
    //1. Get system time, and use
    bool bStatus = false;
    try
    {

        SYSTEMTIME localtime;
        GetLocalTime(&localtime);//Get local time, so that we may pull out HHMMSSmmm

        LARGE_INTEGER li;
        char cNT[MAX_STRING_LENGTH];//new time.
        memset(cNT, '\0', sizeof(cNT));
        try
        {
            //Try to get the performance counter,
            //if one is provided by the OEM.

            QueryPerformanceCounter(&li);//This function retrieves the current value of the 
                                         //high-resolution performance counter if one is provided by the OEM
                                         //We use the first four bytes only of it.
            sprintf(cNT, "%u", li.QuadPart);
        }
        catch(...)
        {
            //Not provided by OEM.
            //Lets go with the GetTickCounts();
            //ddHHMMSS + 4 bytes of dwTicks
            sprintf(cNT,"%04d", GetTickCount());
        }


        //Get the first four bytes.
        int iSkipTo     = 0;//This is incase we'd decide to pull out next four bytes, rather than first four bytes.
        int iGetChars   = 4;//Number of chars to get.
        char *pSub = (char*) malloc(iGetChars+1);//Clear memory
        strncpy(pSub, cNT + iSkipTo, iGetChars);//Get string
        pSub[iGetChars] = '\0'; //Mark end.

        //Prepare unique id
        sprintf(caUID, "%02d%02d%02d%3d%s", 
                                    localtime.wHour, 
                                    localtime.wMinute, 
                                    localtime.wSecond, 
                                    localtime.wMilliseconds, 
                                    pSub); //First four characters concat.

        bStatus = true;
    }
    catch(...)
    {
        //Couldnt prepare. There was some problem.
        bStatus = false;
    }

    return bStatus;
}

Im Anschluss ist die Ausgabe, die ich bekommen:

Einzigartig: [125907 462224] Einzigartig: [125907 462225] Einzigartig: [125907 462226] Einzigartig: [125907 462227] Einzigartig: [125907 462228] Einzigartig: [125907 462230] Einzigartig: [125907 462231] Einzigartig: [125907 462232] Einzigartig: [125907 462233] Einzigartig: [125907 462234] Einzigartig: [125907 462235] Einzigartig: [125907 462237] Einzigartig: [125907 462238] Einzigartig: [125907 462239] Einzigartig: [125907 462240] Einzigartig: [125907 462241] Einzigartig: [125907 462243] Einzigartig: [125907 462244] Einzigartig: [125907 462245] Einzigartig: [125907 462246] Einzigartig: [125907 462247] Einzigartig: [125907 462248] Einzigartig: [125907 462249] Einzigartig: [125907 462251] Einzigartig: [125907 462252] Einzigartig: [125907 462253] Einzigartig: [125907 462254] Einzigartig: [125907 462255] Einzigartig: [125907 462256] Einzigartig: [125907 462257] Einzigartig: [125907 462258] Millisekunde geändert, 46 Einzigartig: [125907 622261] Einzigartig: [125907 622262] Einzigartig: [125907 622263] Einzigartig: [125907 622264] Einzigartig: [125907 622265] Einzigartig: [125907 622267] Einzigartig: [125907 622268] Einzigartig: [125907 622269] Einzigartig: [125907 622270] Einzigartig: [125907 622271] Einzigartig: [125907 622273] Einzigartig: [125907 622274] Einzigartig: [125907 622275] Einzigartig: [125907 622276] Einzigartig: [125907 622277] Einzigartig: [125907 622278] Einzigartig: [125907 622279] Einzigartig: [125907 622281] Einzigartig: [125907 622282] Einzigartig: [125907 622283] Einzigartig: [125907 622284] Einzigartig: [125907 622285] Einzigartig: [125907 622286] Einzigartig: [125907 622288] Einzigartig: [125907 622289] Einzigartig: [125907 622290] Einzigartig: [125907 622291] Einzigartig: [125907 622292] Einzigartig: [125907 622293] Einzigartig: [125907 622295] Einzigartig: [125907 622296] Einzigartig: [125907 622297] Einzigartig: [125907 622298] Einzigartig: [125907 622299] Einzigartig: [125907 622300] Einzigartig: [125907 622301] Einzigartig: [125907 622302] Einzigartig: [125907 622304] Einzigartig: [125907 622305] Einzigartig: [125907 622306] Millisekunde geändert, 62 Einzigartig: [125907 782308] Einzigartig: [125907 782310] Einzigartig: [125907 782311] Einzigartig: [125907 782312] Einzigartig: [125907 782313] Einzigartig: [125907 782314] Einzigartig: [125907 782316] Einzigartig: [125907 782317] Einzigartig: [125907 782318] Einzigartig: [125907 782319] Millisekunde geändert, 125 Einzigartig: [1259071402495] Einzigartig: [1259071402497] Einzigartig: [1259071402498] Einzigartig: [1259071402499] Einzigartig: [1259071402500] Einzigartig: [1259071402502] Einzigartig: [1259071402503] Einzigartig: [1259071402504] Einzigartig: [1259071402505] Einzigartig: [1259071402507]

Jetzt von Ich denke die generierten IDs in einer Liste zu halten, und vergleichen Sie die neue erzeugte man mit den bestehenden in der Liste. Wenn es bereits in der Liste vorhanden ist, dann gut kann ich sicherlich die Nummer überspringt und andere erzeugt, aber sicher und klar würde diese Logik nicht.

Würde schätzen Ihre Kommentare / Anregungen / Aktuelles / etc.

Danke JT.

War es hilfreich?

Lösung

war meine Lösung die Systemzeit zu erhalten und einen Zähler zu, dass (Pseudo-Code) hinzufügen:

static int counter = 0;
static Time lastTime;

String getNextId() {
    Time now = System.getTime();
    if (lastTime == now)
        counter ++;
    else
        counter = 0;
    return now+counter;
}

Dies würde garantieren, dass ich auch eine neue ID bekommen würde, wenn ich die Methode häufiger als getTime() Änderungen genannt.

Andere Tipps

Die Logik scheint mir klingen, wenn man es von einer Maschine auf einem Single-Core-Prozessor laufen. Ich weiß nicht, ob das gleiche für einen Multi-Core-Prozessor für aufeinanderfolgende Anrufe hält jedoch. Die generierten Zahlen werden auf jeden Fall nicht über Maschinen eindeutig sein, aber.

Aus Neugier, gibt es einen Grund Sie nicht GUIDs verwenden?

Oder da Sie erwägen, die generierten IDs in einer Liste zu halten vergleichen zu können, warum können Sie nicht einen Generator erstellen? Da Sie Speicher vorschlagen, ist eine Option, wenn Sie die zuletzt verwendete Nummer speichern und jeden Einsatz erhöhen ... können Sie auch ein Datum speichern und den Zähler täglich zurückgesetzt, wenn Sie es wünschen.

Ich habe Probleme mit mal in schnellen Schleifen hatte, wo sie trotz es gesunden Menschenverstand nicht geändert haben wird sie sollten (Sie haben keine Kontrolle über das Betriebssystem, so dass Sie nicht davon ausgehen kann, dass die Zeit alle x Millisekunden usw. ändert.)

den Zählerwert als eine extra paar Ziffern Hinzufügen (nicht als Zuwachs) und es bei einem Neustart oder nach 9999 Zurücksetzen sollen diese genug verstecken, um es so gut wie unmöglich (berühmte letzte Worte) zu geschehen.

Format ist dann TTTTTToooo wo T Ihre Zeit Figur ist und o Ihre 4-stellige gegenüber.

Aaron: Vielen Dank für Ihre Kommentare, habe ich Ihren Ansatz zu bekommen, was ich wollte.

__forceinline bool GetUniqueIDEx(char caUID[MAX_STRING_LENGTH])
{
    //Logic: Add HHMMSSmmm with 3 bytes counter.
    //Guarantees a unique number for a calendar date, 
    //that in a single milli second band (0 to 999) the three bytes 
    //of counter would always be unique.
    //1. Get system time, and use

    bool bStatus = false;
    try
    {
        GetLocalTime(&localtime);//Get local time, so that we may pull out HHMMSSmmm

        char cNT[MAX_STRING_LENGTH];//new time.
        memset(cNT, '\0', sizeof(cNT));
        if(m_nCounter> MAX_COUNTER_LIMIT)
        {
            m_nCounter= 0;
        }

        sprintf(cNT, "%03d", ++m_nCounter);

        //Prepare unique id
        sprintf(caUID, "%02d%02d%02d%03d%s", 
                                            localtime.wHour, 
                                            localtime.wMinute, 
                                            localtime.wSecond, 
                                            localtime.wMilliseconds, 
                                            cNT); 

        bStatus = true;
    }
    catch(...)
    {
        //Couldnt prepare. There was some problem.
        bStatus = false;
    }

    return bStatus;
}

würde ich Sekunden seit Mitternacht verwenden und dann einen Zähler. Dies gibt Ihnen bis zu zehn Millionen Zugriffe pro Sekunde. Sollte ziemlich eindeutig sein. Mit Aarons Code oben, formatieren Sie die Zeichenfolge wie:

sprintf(idstr, "%05d%07d", secs_since_midnight, counter);

Natürlich, ich bin auch fest davon überzeugt, sich mit der Basis-36 (via itoa), wenn Sie wirklich wollen, einen Zähler in ein paar druckbare Zeichen stopfen (und Tag des Jahres statt Monat / Tag, etc.)

Ich bin mir nicht sicher, ob Ihr Prozess winziges Performance-Problem opfern kann und die Logik einfach zu halten.

Wir garantieren eindeutige Nummer mit HHMMSSmmm Format selbst wenn Sie Ihren Prozess zwischen zwei Anrufen für 1 Millisekunde bis eingeschläfert. Auf diese Weise können Sie die Verkettung Teil eliminieren und auch die Liste, die Sie pflegen müssen, um verdoppeln die Einzigartigkeit überprüfen.

Manikanthan Velayutham // programmiert, groß zu denken

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top