このコードを使用して、8桁の一意の番号を生成しています。
byte[] buffer = Guid.NewGuid().ToByteArray();
return BitConverter.ToUInt32(buffer, 8).ToString();
このコードは実際に一意の番号を生成しますか、それとも同じ番号を繰り返しますか?
A GUIDは単なる乱数ではなく、セグメントで構成されています。同じコンピューター上でGUIDが生成された場合、一部のセグメントはまったく変更されません。64ビットの元の128ビットは、GUIDの構造を壊しており、生成された数値の一意性を壊している可能性があります。
この 質問 には、GUIDの一意性に関する詳細情報があります。一意の番号が必要な場合に、GUIDの一部のみを使用することが悪い理由の詳細については、 このリンク も確認してください。
重複を絶対的な最小値に制限する必要がある場合は、増分カウンターが必要なものを提供します。アプリケーションが複数のスレッドまたはプロセスを使用している場合、カウンターを正しく実装するのが難しい(または不可能でさえある)場合があります。
これは、複数のマシン間で一意になるようにGUIDが設計されたレルムです。したがって、マシン間の一意性が要件である場合は、guidを使用する必要があります。全体のガイド。
任意のランダムシーケンスは、いくつかの衝突を持つようにバインドされています。それはただの問題です。 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をどこかに配置して、毎回新しいものを作成しないようにすることもできます。
これは別のバージョンです
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");
}
それはユニークであることを保証します!
私の最初の答えは一意性の問題を扱っていませんでした。私の2つ目は:
static int counter;
public static int GetUniqueNumber()
{
return counter++;
}
アプリの再起動全体で一意の番号を使用する場合は、GetUniqueNumberを呼び出した後、counterの値をデータベースまたは他の場所に永続化する必要があります。
このメソッドはランダムな文字列を生成し、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%の一意のシーケンスを得るには、古い生成値を永続化し、新しく作成された値の一意性を確認する必要があります。
値の範囲が小さすぎます。 ERPシステム-最初の顧客番号を1000に設定し、次の番号は1001、1002、...、99999999のように、増分カウンターが最良のソリューションです。それ以外の場合、これらからランダムな番号(またはGUIDの一部)を取得すると、同じ番号に再度ヒットします。アプリによっては、遅かれ早かれ、反復するよりも早く発生することが保証されています。
10000000から99999999の間の一意の数値が必要な場合は、10000000から整数を開始し、それを増分し始めます。順番に並べられた番号を生成することは、他の生成されたシーケンスと同じくらいランダムであり、生成がずっと簡単です。
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;
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;