在我的网站上,我允许人们批量购买我网站的订阅(我称之为优惠券)。一旦他们获得这些优惠券,他们就会将其交给任何人,然后将代码输入到他们的帐户中以进行升级。
现在我正在考虑做 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);
现在我认为这会给我足够多的组合,如果我用完了,我总是可以增加代码的长度。我想保持简短,因为我不希望用户必须输入大量数字。
我也没有时间制定更优雅的解决方案,也许他们点击电子邮件中的链接或其他内容,就会激活他们的帐户,当然,这会减少有人试图随机猜测优惠券号码的情况。
如果网站变得更受欢迎,我会处理这些事情。
我想知道如何处理同一张优惠券可能重复生成的情况。我的第一个想法是每次创建凭证时检查数据库,如果存在则创建一个新的。
但是这看起来可能会很慢。所以我想也许首先获取所有 key 并将它们存储在内存中,然后他们在那里进行检查,但如果列表不断增长,我可能会遇到内存不足异常和所有这些很棒的东西。
那么有人有什么想法吗?或者我是否坚持执行上面列出的两种方法之一?
我正在使用 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;
}
}
}
最佳答案
这会很慢,因为您想要随机生成优惠券,然后检查数据库中的每个生成的代码。
我将创建一个表vouchers
,其中包含 ID、代码和 is_used 列。我会用足够的随机代码填充该表一次。由于这可以在单独的进程中完成,因此性能不会成为太大的问题。让它在晚上运行,第二天您就会得到一张填满的优惠券表。
如果您想防止生成重复的优惠券,这不是问题。您无论如何都可以生成它们,并将它们放入 System.Collections.Generic.HashSet 中(这可以防止添加重复项而不引发异常),或者在将它们添加到该凭证之前调用 Linq 方法 Distinct() > 表。
关于c# - 使用 Nhibernate 检查已用 key 的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11565414/