web-dev-qa-db-fra.com

Comment générer un numéro unique qui ne se répète pas dans un délai raisonnable?

J'intègre/teste avec un service Web distant et même s'il s'agit du point de terminaison "QA", il applique toujours une adresse e-mail unique lors de chaque appel.

Je peux penser à DateTime.Now.Ticks (Par exemple 634970372342724417) et Guid.NewGuid(), mais aucun de ceux-ci ne peut être fusionné dans un e-mail avec max. 20 caractères (ou peuvent-ils?).

Je suppose que ce n'est pas si difficile d'écrire dans un fichier un nombre qui contient le dernier numéro utilisé, puis d'utiliser [email protected], [email protected], etc... Mais si je peux éviter de persister, je le fais toujours.

Quelqu'un at-il une astuce ou un algorithme qui donne quelque chose d'un "guid" de courte durée qui est unique à une période de temps raisonnablement longue (disons un an) que je pourrais utiliser pour mes adresses e-mail de longueur maximale 20 caractères avec (longueur maximale de guid) = 14 = 20 - longueur de "@ x.com"?

13
Aaron Anodide

Si vous supposez que vous ne générerez pas deux adresses e-mail en même temps, vous pouvez en effet utiliser les ticks pour générer une adresse e-mail.

Cependant, si ticks est un nombre 64 bits et que vous écrivez ce nombre, vous vous retrouverez avec plus de 20 caractères.

L'astuce consiste à coder votre numéro 64 bits en utilisant un schéma différent. Supposons que vous pouvez utiliser les 26 caractères de l'alphabet occidental + 10 chiffres. Cela rend 36 caractères possibles. Si vous prenez 5 bits, vous pouvez représenter 32 caractères. Cela devrait suffire. Prenez les 64 bits et divisez-les en groupes de 5 bits (64/5 correspond à environ 13 groupes). Traduisez tous les 5 bits en un seul caractère. De cette façon, vous vous retrouvez avec 13 caractères, et vous pouvez toujours ajouter un caractère devant).

long ticks = DateTime.Now.Ticks;
byte[] bytes = BitConverter.GetBytes(ticks);
string id = Convert.ToBase64String(bytes)
                        .Replace('+', '_')
                        .Replace('/', '-')
                        .TrimEnd('=');
Console.WriteLine (id);

Rendements:

Gq1rNzbezwg
20
Patrick

Puisque vous avez spécifié au moins 1 seconde entre chaque appel, cela devrait fonctionner:

DateTime.Now.ToString("yyyyMMddHHmmss");

ses 14 caractères exactement.

12
Abdusalam Ben Haj

Si vous obtenez les chiffres suivants de votre date-heure, vous devriez pouvoir le faire fonctionner ... Par exemple:

DateTime.Now.ToString("yyMMddHHmmssff");

qui est de 16 caractères, laissant 4 pour un autre préfixe selon vos besoins.

Donc, le 21 février 2013, vers 10 h 21 serait "130321102142" et le suivant serait "130321102169", etc ...

Jetez un œil à http://msdn.Microsoft.com/en-us/library/zdtaw1bw.aspx pour plus de détails sur le formatage datetime.

10
EtherDragon
    /// <summary>
    /// Get a unique reference number.
    /// </summary>
    /// <returns></returns>
    public string GetUniqueReferenceNumber(char firstChar)
    {
        var ticks = DateTime.Now.Ticks;
        var ticksString = ticks.ToString();
        var ticksSubString = ticksString.Substring((ticksString.Length - 15 > 0) ? ticksString.Length - 15 : 0); 
        if (this.currentTicks.Equals(ticks))
        {
            this.currentReference++;

            if (this.currentReference >= 9999)
            {
                // Only when there are very fast computers.
                System.Threading.Thread.Sleep(1);
            }

            return (firstChar + ticksSubString + this.currentReference.ToString("D4")).PadRight(20, '9');
        }

        this.currentReference = -1;
        this.currentTicks = ticks;
        return (firstChar + ticksSubString).PadRight(20, '9');
    }

Dans mon cas, je devais créer un numéro de référence unique avec un premier caractère unique et un maximum de 20 caractères. Vous pouvez peut-être utiliser la fonction ci-dessous, elle vous permet de créer 9999 numéros uniques en une seule fois. (zéro inclus)

Bien sûr, vous pouvez créer votre propre implémentation sans le premier caractère et le nombre maximal de caractères de 20

0
Martijn Willegers

Juste pour ajouter ... Si vous souhaitez utiliser le nombre uniquement à partir des graduations, vous pouvez utiliser substring, par exemple:

int onlyThisAmount = 20;
string ticks = DateTime.Now.Ticks.ToString();
ticks = ticks.Substring(ticks.Length - onlyThisAmount);
0
Michel Ayres