Comment générer un nombre unique de 8 chiffres?

J’utilise ce code pour générer un numéro unique à 8 chiffres.

byte[] buffer = Guid.NewGuid().ToByteArray(); return BitConverter.ToUInt32(buffer, 8).ToSsortingng(); 

Ce code génère-t-il vraiment un numéro unique ou peut-il répéter le même numéro?

Un GUID n’est pas simplement un nombre aléatoire; il est composé de segments. Certains des segments ne changeront pas du tout si le guide est généré sur le même ordinateur. En n’utilisant que 64 bits des 128 bits d’origine, vous rompez la structure du GUID et probablement le caractère unique du nombre généré.

Cette question contient plus d’informations sur le caractère unique des astuces, consultez également ce lien pour savoir pourquoi il est mauvais d’utiliser une partie seulement d’un guide si vous avez besoin d’un numéro unique.

Si vous devez limiter la duplication à un minimum absolu, un compteur incrémentiel vous donnera ce dont vous avez besoin. Si votre application utilise plusieurs threads ou processus, il peut être difficile (voire impossible) d’implémenter un compteur correctement.

C’est le domaine dans lequel les écrans ont été conçus pour être uniques sur plusieurs machines. Ainsi, si l’unicité des machines est une exigence, vous devez utiliser des guids. Le guid entier.

Toute séquence aléatoire est liée à certaines collisions. C’est juste une question de quand. En utilisant la formule du paradoxe de l’anniversaire, avec 100 000 000 de valeurs possibles (8 chiffres), la probabilité que vous ayez une collision avec seulement 10 000 éléments est d’environ 40% et de 99% avec 30 000 éléments. ( voir ici pour une calculasortingce ).

Si vous avez vraiment besoin d’une séquence aléatoire, vous ne devez pas utiliser de GUID à cette fin. Les GUID ont une structure très spécifique et ne doivent être considérés que dans leur ensemble. Il est assez facile de créer un générateur de séquence aléatoire de 8 chiffres. Cela devrait vous donner une séquence de 8 chiffres:

  public ssortingng Get8Digits() { var bytes = new byte[4]; var rng = RandomNumberGenerator.Create(); rng.GetBytes(bytes); uint random = BitConverter.ToUInt32(bytes, 0) % 100000000; return Ssortingng.Format("{0:D8}", random); } 

Vous pouvez également prendre le RandomNumberGenerator et le placer quelque part pour éviter de créer un nouveau à chaque fois.

Voici une autre version

 public static ssortingng GetFormNumber() { byte[] buffer = Guid.NewGuid().ToByteArray(); var FormNumber = BitConverter.ToUInt32(buffer, 0) ^ BitConverter.ToUInt32(buffer, 4) ^ BitConverter.ToUInt32(buffer, 8) ^ BitConverter.ToUInt32(buffer, 12); return FormNumber.ToSsortingng("X"); } 

ça assure d’être unique!

Ma première réponse n’a pas abordé le problème de l’unicité. Mon deuxième fait:

 static int counter; public static int GetUniqueNumber() { return counter++; } 

Si vous souhaitez avoir des numéros uniques lors des redémarrages d’applications, vous devez conserver la valeur de compteur dans une firebase database ou ailleurs après chaque appel GetUniqueNumber.

La plage de valeurs est trop petite. Un compteur incrémentiel est la meilleure solution, comme dans un système ERP – vous définissez le premier numéro de client sur 1000 et le suivant sur 1001, 1002, …, 99999999. Sinon, si vous obtenez un nombre aléatoire (ou une partie du GUID) à partir de ceux-ci, vous frappez à nouveau le même nombre. En fonction de votre application, tôt ou tard, mais il est certain que cela se produira plus tôt que de simplement les parcourir.

Cette méthode va générer une chaîne aléatoire, elle ne s’appuie pas sur la méthode Random et est bien meilleure que l’approche guid:

 public static ssortingng gen_Digits(int length) { var rndDigits = new System.Text.SsortingngBuilder().Insert(0, "0123456789", length).ToSsortingng().ToCharArray(); return ssortingng.Join("", rndDigits.OrderBy(o => Guid.NewGuid()).Take(length)); } 

vous pouvez augmenter la longueur pour réduire les risques de collision, mais pour avoir une séquence unique à 100%, vous devez conserver les anciennes valeurs générées et vérifier si la valeur nouvellement créée est unique.

Si vous voulez un nombre unique compris entre 10000000 et 99999999, démarrez un entier compris entre 10000000 et commencez simplement à l’incrémenter. La génération de nombres séquentiellement ordonnés n’est pas moins aléatoire que n’importe quelle autre séquence générée, et bien plus facile à générer.

Si vous exprimez le non sous la forme d’une combinaison de jour (2 chiffres), d’heure (2 chiffres), de minutes (2 chiffres), de seconde (2 chiffres) et d’année (4 chiffres), il s’agira alors de 12 chiffres mais toujours d’un numéro unique.

  DateTime _now = DateTime.Now; ssortingng _dd = _now.ToSsortingng("dd"); // ssortingng _mm = _now.ToSsortingng("MM"); ssortingng _yy = _now.ToSsortingng("yyyy"); ssortingng _hh = _now.Hour.ToSsortingng(); ssortingng _min = _now.Minute.ToSsortingng(); ssortingng _ss = _now.Second.ToSsortingng(); ssortingng _uniqueId= _dd+ _hh+ _mm+_min+_ss + _yy; 
 System.Threading.Thread.Sleep(1); long code = (long)DateTime.UtcNow.Subtract(new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds; 

OU

 System.Threading.Thread.Sleep(1000); long code = (long)DateTime.UtcNow.Subtract(new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;