私のサイトでは、人々が私のサイトへのサブスクリプションをまとめて購入できるようにしています (バウチャーと呼んでいます)。これらのバウチャーを入手したら、誰にでも渡し、そのコードをアカウントに入力してアップグレードします。
現在、4つの英数字コード(大文字、小文字、数字)を実行することを考えており、次のようなものになります
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var stringChars = new char[4];
var random = new Random();
for (int i = 0; i < stringChars.Length; i++)
{
stringChars[i] = chars[random.Next(chars.Length)];
}
var finalString = new String(stringChars);
今のところ、これで十分な組み合わせが得られると思います。不足した場合は、いつでもコードの長さを増やすことができます。ユーザーが巨大な数字を入力する必要がないので、短くしたいと思います。
また、より洗練されたソリューションを作成する時間もありません。おそらく、メール内のリンクまたは何かをクリックしてアカウントがアクティブになり、もちろんこれにより、バウチャー番号をランダムに推測しようとする人が削減されます.
これらは、サイトの人気が高まった場合に私が対処することです.
同じバウチャーの重複生成の可能性をどのように処理できるか疑問に思っています。私が最初に考えたのは、バウチャーが作成されるたびにデータベースをチェックし、存在する場合は新しいバウチャーを作成することでした。
ただし、それは遅くなる可能性があるようです。そのため、最初にすべてのキーを取得してメモリに保存し、そこでチェックすることも考えましたが、リストが大きくなり続けると、メモリ不足の例外やその他すべての素晴らしいことが発生する可能性があります。
誰にもアイデアはありますか?それとも、上記の 2 つの方法のいずれかを実行するのに行き詰まっていますか?
nhibernate、asp.net mvc、および C# を使用しています。
編集
static void Main(string[] args)
{
List<string> hold = new List<string>();
for (int i = 0; i < 10000; i++)
{
HashAlgorithm sha = new SHA1CryptoServiceProvider();
byte[] result = sha.ComputeHash(BitConverter.GetBytes(i));
string hex = null;
foreach (byte x in result)
{
hex += String.Format("{0:x2}", x);
}
hold.Add(hex.Substring(0,3));
Console.WriteLine(hex.Substring(0, 4));
}
Console.WriteLine("Number of Distinct values {0}", hold.Distinct().Count());
}
上記は、ハッシュを使用しようとする私の試みです。ただし、予想よりもかなり多くの重複があるように見えるため、何かが欠けていると思います。
編集 2
欠けていたものを追加したと思いますが、これが彼の意図したものかどうかはわかりません. また、移動できる限り移動した場合にどうすればよいかわかりません(移動できる場所の長さが40になるようです)。
static void Main(string[] args)
{
int subStringLength = 4;
List<string> hold = new List<string>();
for (int i = 0; i < 10000; i++)
{
SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
byte[] result = sha.ComputeHash(BitConverter.GetBytes(i));
string hex = null;
foreach (byte x in result)
{
hex += String.Format("{0:x2}", x);
}
int startingPositon = 0;
string possibleVoucherCode = hex.Substring(startingPositon,subStringLength);
string voucherCode = Move(subStringLength, hold, hex, startingPositon, possibleVoucherCode);
hold.Add(voucherCode);
}
Console.WriteLine("Number of Distinct values {0}", hold.Distinct().Count());
}
private static string Move(int subStringLength, List<string> hold, string hex, int startingPositon, string possibleVoucherCode)
{
if (hold.Contains(possibleVoucherCode))
{
int newPosition = startingPositon + 1;
if (newPosition <= hex.Length)
{
if ((newPosition + subStringLength) > hex.Length)
{
possibleVoucherCode = hex.Substring(newPosition, subStringLength);
return Move(subStringLength, hold, hex, newPosition, possibleVoucherCode);
}
// return something
return "0";
}
else
{
// return something
return "0";
}
}
else
{
return possibleVoucherCode;
}
}
}