سؤال

وأردت عددا من شأنها أن تبقى فريدة من نوعها ليوم واحد (24 ساعة). وفيما يلي التعليمات البرمجية التي خطرت لي. وكنت أتساءل عن المغالطات / مخاطره المحتملة. "أعتقد أن" هذا يضمن الرقم 12 رقم فريد ليوم أتلست.

والمنطق هو الحصول على التاريخ / الوقت الحالي (hhmmssmmm) وCONCAT بايت الأربعة الأولى من نتيجة عداد الأداء الاستعلام.

__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;
}

وفيما يلي الإخراج الذي أحصل:

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

والآن أنا أفكر في الحفاظ على هوية ولدت في القائمة، ومقارنتها إنشاء واحدة جديدة مع تلك الموجودة في القائمة. إذا كانت موجودة بالفعل في القائمة، ثم جيدا يمكنني تخطي بالتأكيد عدد وتوليد أخرى، ولكن من المؤكد والواضح أن تفشل هذا المنطق.

وسوف نقدر تعليقاتكم / اقتراحات / التحديثات / الخ.

والشكر JT.

هل كانت مفيدة؟

المحلول

وكان لي حل للحصول على وقت النظام وإضافة عداد إلى أن (رمز زائف):

static int counter = 0;
static Time lastTime;

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

وهذا من شأنه أن يضمن أن كنت تحصل على ID جديد حتى عندما كنت استدعاء الأسلوب في كثير من الأحيان تغييرات getTime().

نصائح أخرى

والمنطق يبدو يبدو لي إذا كنت تشغيله من جهاز واحد على معالج أحادي النواة. أنا لا أعرف إذا كان الشيء نفسه ينطبق على معالج متعدد النوى للمكالمات متتالية، ولكن. فإن الأرقام الناتجة بالتأكيد لا تكون فريدة من نوعها عبر الأجهزة، ولكن.

وبدافع الفضول، هناك سبب كنت لا تستخدم المعرفات الفريدة العمومية؟

وأو منذ كنت تفكر في الحفاظ على هوية ولدت في قائمة للمقارنة، لماذا لا يمكنك إنشاء مولد؟ منذ يوحي لك تخزينه هو خيار مطروح، إذا قمت بتخزين رقم المستخدم الماضي، وزيادة في كل استخدام ... يمكنك تخزين حتى موعد وإعادة تعيين العداد كل يوم إذا كنت ترغب في ذلك.

ولقد كان لي مشاكل مع مرات في حلقات سريعة حيث أنها لم تتغير على الرغم من كونها الحس السليم ينبغي لهم (لا يوجد لديك السيطرة على نظام التشغيل بحيث لا يمكن أن نفترض أن الوقت يتغير كل س ميلي ثانية الخ.)

وإضافة قيمة العداد باعتباره رقما قليلة اضافية (وليس بوصفه زيادة) وإعادة على إعادة تشغيل أو بعد 9999 يجب إخفاء هذا يكفي لجعل كل شيء ولكن من المستحيل أن يحدث (الشهيرة الكلمات الأخيرة).

والتنسيق ومن ثم TTTTTToooo حيث T هو الرقم وقتك وس 4 أرقام، أوفست.

وهارون: شكرا لتعليقاتكم، كنت نهجكم للحصول على ما أردت.

__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;
}

وأود أن استخدام الثواني منذ منتصف الليل وبعد ذلك العداد. وهذا يعطي ما يصل الى عشرة ملايين زيارة في ثواني. يجب أن تكون فريدة من نوعها إلى حد ما. باستخدام رمز هارون أعلاه، قمت بتهيئة سلسلة النحو التالي:

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

وبطبيعة الحال، أنا أيضا من أشد المؤمنين في استخدام قاعدة 36 (عبر itoa) عندما كنت تريد حقا أن الالزام مضادة في عدد قليل من الشخصيات للطباعة (ويوم من أيام العام بدلا من شهر / يوم، الخ.)

ولست متأكدا ما إذا كانت العملية الخاصة بك يمكن أن تضحي مشكلة أداء صغيرة والحفاظ على منطق بسيط.

ونستطيع أن نضمن رقم فريد مع شكل HHMMSSmmm نفسها إذا وضعت عملية لنوم ل1 ميلي ثانية واحدة بين اثنين من المكالمات. وبهذه الطريقة تتمكن من القضاء على جزء سلسلة وأيضا قائمة لديك للحفاظ على لمضاعفة التحقق من التفرد.

وManikanthan Velayutham // مبرمجة للتفكير BIG

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top