简体   繁体   English

将C#system.Random与14个字符始终保证是唯一的字符串(哈希)

[英]Will C# system.Random with 14 characters always be guaranteed to be unique string (hash)

I have a utility function in which I want to have as part of my URL querystring . 我有一个实用程序函数,希望将其作为URL querystring的一部分。 I need to be sure that it is always unique 我需要确保它始终是唯一的

public static string RandomString(int length)
{
   const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz0123456789";
   var random = new Random();
   return new string(Enumerable.Repeat(chars, length)
     .Select(s => s[random.Next(s.Length)]).ToArray());
}

If say I pass in 14 for the length , This generates hash like 如果说我输入了14的长度,这会生成像

 YS5bwVTjwEBhFp
 sNi6EfU5rUxI2Z
 sQKhqhklw22vb2

If i'm using talking about 20,000 uses a year of this, Is it safe to say that it should always be unique? 如果我正在谈论每年使用20,000次,是否可以肯定地说它应该始终是唯一的?

Again 再次

http://:mywebsite.com?id=sQKhqhklw22vb2 is how i would use it http://:mywebsite.com?id = sQKhqhklw22vb2是我将如何使用它

One way to ensure uniqueness is to save the generated values and validate before using that was never used in the past. 确保唯一性的一种方法是保存生成的值并在使用之前从未使用过的值之前进行验证。 An alternative is to pre-generate a large number of values, save them in a table, then pick the next available. 一种替代方法是预先生成大量值,将它们保存在表中,然后选择下一个可用值。 Variations on this theme are the only way to ensure uniqueness if the parameter has no meaning (no semantics). 如果参数没有意义(没有语义),则对此主题进行变体是确保唯一性的唯一方法。

Another way is to add meaning. 另一种方法是添加含义。 Instead of YS5bwVTjwEBhFp , sNi6EfU5rUxI2Z etc use 0 , 1 etc (an incremental value coming from DB). 代替YS5bwVTjwEBhFpsNi6EfU5rUxI2Z等使用01等(增量值从DB推出)。 Of course, you can encode this, eg. 当然,您可以对此进行编码,例如。 by encryption, into a value that has no meaning for user, so the user still see sNi6EfU5rUxI2Z but that is base64 encoded encrypted value of 1 or something like that. 通过加密,转换为对用户没有意义的值,因此用户仍会看到sNi6EfU5rUxI2Z但这是base64编码的加密值1或类似值。

And finally, for all practical uses, just using a cryptographic random string (ie. RNGCryptoServiceProvider.GetBytes ) should be more than enough. 最后,对于所有实际用途,仅使用加密随机字符串(即RNGCryptoServiceProvider.GetBytes )就足够了。 Not guaranteed unique, but hugely improbable to collide. 保证唯一,但极不可能发生碰撞。

Not sure if your System.Random is that great, but you could combine with a much better Cryptopgraphy scheme. 不知道您的System.Random是否这么好,但是您可以结合使用更好的密码方案。 10 of your characters and 40 of better... 您的10个角色和40个以上的角色...

Here it is in Linqpad 这是在Linqpad中

example : yours generates h0UcVayzu2 the other better one generates LyR7SUYZ-ZPll36wzGI5kMPamKtyXV_rN0Ax6iZG 示例:您的生成h0UcVayzu2 ,另一个更好的生成LyR7SUYZ-ZPll36wzGI5kMPamKtyXV_rN0Ax6iZG

Combined is then 50 characters 然后是50个字符

h0UcVayzu2LyR7SUYZ-ZPll36wzGI5kMPamKtyXV_rN0Ax6iZG

Code: 码:

void Main()
{

    var x = RandomString(10);
    x.Dump();

    var y = Example.GenerateIdentifier(40);
    y.Dump();

    var z = x + y;

    z.Dump();


}


public static string RandomString(int length)
{
  const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz0123456789";
  var random = new Random();
  return new string(Enumerable.Repeat(chars, length)
    .Select(s => s[random.Next(s.Length)]).ToArray());
}


public class Example {
  static readonly char[] AvailableCharacters = {
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 
    'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
  };

  internal static string GenerateIdentifier(int length) {
    char[] identifier = new char[length];
    byte[] randomData = new byte[length];

    using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) {
      rng.GetBytes(randomData);
    }

    for (int idx = 0; idx < identifier.Length; idx++) {
      int pos = randomData[idx] % AvailableCharacters.Length;
      identifier[idx] = AvailableCharacters[pos];
    }

    return new string(identifier);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM