在我的网站上,我允许人们批量购买我网站的订阅(我称它们为优惠券)。一旦他们拥有这些代金券,他们就会将其提供给任何人,然后将代码输入他们的帐户以进行升级。
现在我正在考虑做 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);
现在我认为这会给我足够多的组合,如果我真的用完了,我总是可以增加代码的长度。我想保持简短,因为我不希望用户输入大量的数字。
我也没有时间制定更优雅的解决方案,也许他们单击电子邮件中的链接或其他内容并激活他们的帐户,当然这会减少试图随机猜测凭证号的人。
如果每个网站都变得更受欢迎,我会处理这些事情。
我想知道如何处理同一凭证的可能重复生成。我的第一个想法是每次创建凭证时检查数据库,如果存在则创建一个新的。
但是,这似乎可能很慢。所以我想也可能首先获取所有密钥并将它们存储在内存中,然后他们会在那里检查,但如果列表不断增长,我可能会遇到内存不足异常和所有这些好东西。
那么有人有什么想法吗?还是我坚持做上面列出的两种方法之一?
我正在使用 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;
}
}
}