9 桁の一意のランダム文字列を生成したいと考えています。現在、私は使用しています
Guid.NewGuid().ToString().Replace("-","").Substring(0,9)
しかし、すぐに衝突するのではないかと心配しています。これには何か良い方法がありますか、それともこれで問題ありませんか?
GUID の部分文字列を使用する場合、ランダム性と一意性はまったく保証されません。
ランダム性の要件を満たすには、古い SO の質問に対する私の回答を参照してください。これを行うための基本的なコードは次のとおりです。
public static string CreateRandomString(int length)
{
length -= 12; //12 digits are the counter
if (length <= 0)
throw new ArgumentOutOfRangeException("length");
long count = System.Threading.Interlocked.Increment(ref counter);
Byte[] randomBytes = new Byte[length * 3 / 4];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(randomBytes);
byte[] buf = new byte[8];
buf[0] = (byte)count;
buf[1] = (byte)(count >> 8);
buf[2] = (byte)(count >> 16);
buf[3] = (byte)(count >> 24);
buf[4] = (byte)(count >> 32);
buf[5] = (byte)(count >> 40);
buf[6] = (byte)(count >> 48);
buf[7] = (byte)(count >> 56);
return Convert.ToBase64String(buf) + Convert.ToBase64String(randomBytes);
}
衝突を防ぐために12桁のカウントを提供し、ランダム性のために必要な追加の桁を提供します。12 桁の文字列よりも短くしたい場合は、コードを変更できます。
GUID を使用すると、グローバルに一意であることが保証されますが、全体としてのみです。GUID 全体の部分文字列についてランダム性を想定することはできません。
さらに、同じソースから生成している場合、アルゴリズムが同じ変数の一部、たとえばコンピューターの MAC アドレスを使用するため、部分文字列で衝突が発生しますが、それについては完全にはわかりません。例としては十分ですが。
したがって、GUID の部分文字列からランダムな文字列を作成する場合は、以前のすべての GUID を追跡して、衝突がないようにする必要があります。ラスベガスのアルゴリズムを取得します。
これが私が見つけた最も簡単な答えなので、私は自分の質問に答えることに決めました。同じ文字列を返すランダム文字列ジェネレータへのクレジット
private static Random random = new Random((int)DateTime.Now.Ticks);
private static object locker = new object();
private static string RandomString(int size)
{
StringBuilder builder = new StringBuilder();
char ch;
for (int i = 0; i < size; i++)
{
lock (locker)
{
ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
}
builder.Append(ch);
}
return builder.ToString();
}