c# - 使用 Nhibernate 检查已用 key 的最佳方法?

标签 c# .net asp.net-mvc nhibernate

在我的网站上,我允许人们批量购买我网站的订阅(我称之为优惠券)。一旦他们获得这些优惠券,他们就会将其交给任何人,然后将代码输入到他们的帐户中以进行升级。

现在我正在考虑做 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/

相关文章:

c# - 事件冒泡和 MVP : ASP. NET

.net - 将 64 位偏移量添加到指针

c# - MVC RadioButtonFor 组

asp.net-mvc - 安装 Oracle Developer Tools for Visual Studio 2017 时出错

c# - DbProviderFactories 中未列出的 Oracle 数据提供程序 (ODP.NET)

c# - 使用 Take() 从字节数组中获取字节,在 Take() 之后无法转换回 byte[]

c# - 值被赋予 mysql 命令中的参数,但它没有返回正确的 id

c# - 尝试根据用户的选择启动线程

.net - 使 WPF ListBoxItems 可选

asp.net - VimService55.XmlSerializers.dll 中发生类型 'System.StackOverflowException' 的未处理异常