通过密码术生成唯一号码

时间:2016-02-01 12:09:52

标签: c# cryptography

我正在使用Visual Studio 2013iis-8.5.net 4.5.1
在我的项目中,我想创建8 digit unique number,其中间应以'hypen'分隔,前缀为"MNOP-"。生成的8 digit应继承Cryptography class 我的代码

var bytes = new byte[4];
var rng = RandomNumberGenerator.Create();
rng.GetBytes(bytes);
int random = BitConverter.ToInt32(bytes, 0) % 100000000;
var data = "ABCD-" + random.ToString("####-####");

我按'for loop'创建了10000个值,但有些'random variable'返回负值
提前谢谢。

1 个答案:

答案 0 :(得分:2)

您可以做三件事:

  1. 生成随机值(十进制数字十进制数字)并检查您之前是否创建过它,然后将其存储到预先生成的数字列表中;
  2. 创建一个400到800 MB的表并 shuffle ,然后将其存储在磁盘上并在表中使用偏移量;
  3. 创建一个密钥并将其用于使用与输入完全相同的输出的密码(PRP),并使用计数器,基本上实现格式保留加密。
  4. 您不应该只使用随机数生成器,因为碰撞的机会会随着生成的数量而迅速增加。这是因为生日问题。

    这也意味着如果你想生成很多数字,解决方案1)是不适合的,因为它可能会失速。想象一下,你只剩下一个可用的数字,你有一个400 MB的表,它正在尝试剩下的一个4字节的条目。其他选项要求您分别存储表和偏移量或键和计数器。

    您当前的生成方法不平衡,因为它比正数更容易生成更低的数字。此外,您应该重置最高有效位,因为ToInt32返回 signed,两个补码值%余数运算符,而不是模数算子。

    好的,仅限这一次,一些C#代码,庆祝我的平台铜牌:

    namespace StackOverflow
    {
        class RandomIDGenerator
        {
            private const string FORMAT = "ABCD-####-####";
            private const string TEST_FORMAT = "ABCD-###";
    
    
            private RandomNumberGenerator rng = RandomNumberGenerator.Create();
            private byte[] b = new byte[1];
            private SortedSet<string> previousIDs = new SortedSet<string>();
    
            private char GenerateRandomDigit()
            {
                int x;
                do
                {
                    rng.GetBytes(b);
                    x = b[0] & 0xFF;
                } while (x >= 250);
                int y = x % 10;
                return (char) ('0' + y);
            }
    
            private String GenerateRandomID()
            {
                StringBuilder sb = new StringBuilder(TEST_FORMAT);
                for (int i = 0; i < sb.Length; i++)
                {
                    if (sb[i] == '#')
                    {
                        sb[i] = GenerateRandomDigit();
                    }
                }
                return sb.ToString();
            }
    
            public String GenerateUniqueRandomID()
            {
                string id;
                do
                {
                    id = GenerateRandomID();
                }
                while (previousIDs.Contains(id));
                previousIDs.Add(id);
                return id;
            }
    
            public static void Main(String[] args)
            {
                RandomIDGenerator gen = new RandomIDGenerator();
                for (int i = 0; i < 500; i++)
                {
                    Console.WriteLine(gen.GenerateUniqueRandomID());
                }
    
                Console.WriteLine("Put breakpoint here...");
    
                foreach (string id in gen.previousIDs)
                {
                    Console.WriteLine(id);
                }
    
                Console.WriteLine(gen.previousIDs.Count);
                Console.WriteLine("Put breakpoint here...");
            }
        }
    }