web-dev-qa-db-ja.com

8桁の一意の数を生成する方法は?

このコードを使用して、8桁の一意の番号を生成しています。

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

このコードは実際に一意の番号を生成しますか、それとも同じ番号を繰り返しますか?

17
dev

A GUIDは単なる乱数ではなく、セグメントで構成されています。同じコンピューター上でGUIDが生成された場合、一部のセグメントはまったく変更されません。64ビットの元の128ビットは、GUIDの構造を壊しており、生成された数値の一意性を壊している可能性があります。

この 質問 には、GUIDの一意性に関する詳細情報があります。一意の番号が必要な場合に、GUIDの一部のみを使用することが悪い理由の詳細については、 このリンク も確認してください。

重複を絶対的な最小値に制限する必要がある場合は、増分カウンターが必要なものを提供します。アプリケーションが複数のスレッドまたはプロセスを使用している場合、カウンターを正しく実装するのが難しい(または不可能でさえある)場合があります。

これは、複数のマシン間で一意になるようにGUIDが設計されたレルムです。したがって、マシン間の一意性が要件である場合は、guidを使用する必要があります。全体のガイド。

10

任意のランダムシーケンスは、いくつかの衝突を持つようにバインドされています。それはただの問題です。 100,000,000の可能な値(8桁)の誕生日パラドックス式を使用すると、10,000要素のみとの衝突が発生する可能性は約40%、30,000要素との99%です。 ( 電卓はこちら )。

ランダムシーケンスが本当に必要な場合は、GUIDをこの目的で使用しないでください。GUIDは非常に特殊な構造をしており、全体としてのみ使用する必要があります。ランダム8を作成するのは十分簡単です。数字列ジェネレータ。これにより、8桁の数字列が得られます。

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

また、RandomNumberGeneratorをどこかに配置して、毎回新しいものを作成しないようにすることもできます。

10
Can Gencer

これは別のバージョンです

public static string 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.ToString("X");

    }

それはユニークであることを保証します!

4
Kamran Qadir

私の最初の答えは一意性の問題を扱っていませんでした。私の2つ目は:

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

アプリの再起動全体で一意の番号を使用する場合は、GetUniqueNumberを呼び出した後、counterの値をデータベースまたは他の場所に永続化する必要があります。

3
usr

このメソッドはランダムな文字列を生成し、Randomメソッドに依存せず、guid approchよりもはるかに優れています。

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

衝突の可能性を減らすために長さを増やすことができますが、100%の一意のシーケンスを得るには、古い生成値を永続化し、新しく作成された値の一意性を確認する必要があります。

2
Chtiwi Malek

値の範囲が小さすぎます。 ERPシステム-最初の顧客番号を1000に設定し、次の番号は1001、1002、...、99999999のように、増分カウンターが最良のソリューションです。それ以外の場合、これらからランダムな番号(またはGUIDの一部)を取得すると、同じ番号に再度ヒットします。アプリによっては、遅かれ早かれ、反復するよりも早く発生することが保証されています。

2
Vladislav Zorov

10000000から99999999の間の一意の数値が必要な場合は、10000000から整数を開始し、それを増分し始めます。順番に並べられた番号を生成することは、他の生成されたシーケンスと同じくらいランダムであり、生成がずっと簡単です。

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

OR

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

Noを日(2桁)、時(2桁)、分(2桁)、秒(桁)、年(4桁)の組み合わせとして表すと、12桁になりますが、常に一意の番号はありません。

 DateTime _now = DateTime.Now;
 string _dd = _now.ToString("dd"); //
 string _mm = _now.ToString("MM");
 string _yy = _now.ToString("yyyy");
 string _hh = _now.Hour.ToString();
 string _min = _now.Minute.ToString();
 string _ss = _now.Second.ToString();

 string _uniqueId= _dd+ _hh+ _mm+_min+_ss + _yy;
0
agileDev