簡體   English   中英

將C#system.Random與14個字符始終保證是唯一的字符串(哈希)

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

我有一個實用程序函數,希望將其作為URL querystring的一部分。 我需要確保它始終是唯一的

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());
}

如果說我輸入了14的長度,這會生成像

 YS5bwVTjwEBhFp
 sNi6EfU5rUxI2Z
 sQKhqhklw22vb2

如果我正在談論每年使用20,000次,是否可以肯定地說它應該始終是唯一的?

再次

http://:mywebsite.com?id = sQKhqhklw22vb2是我將如何使用它

確保唯一性的一種方法是保存生成的值並在使用之前從未使用過的值之前進行驗證。 一種替代方法是預先生成大量值,將它們保存在表中,然后選擇下一個可用值。 如果參數沒有意義(沒有語義),則對此主題進行變體是確保唯一性的唯一方法。

另一種方法是添加含義。 代替YS5bwVTjwEBhFpsNi6EfU5rUxI2Z等使用01等(增量值從DB推出)。 當然,您可以對此進行編碼,例如。 通過加密,轉換為對用戶沒有意義的值,因此用戶仍會看到sNi6EfU5rUxI2Z但這是base64編碼的加密值1或類似值。

最后,對於所有實際用途,僅使用加密隨機字符串(即RNGCryptoServiceProvider.GetBytes )就足夠了。 保證唯一,但極不可能發生碰撞。

不知道您的System.Random是否這么好,但是您可以結合使用更好的密碼方案。 您的10個角色和40個以上的角色...

這是在Linqpad中

示例:您的生成h0UcVayzu2 ,另一個更好的生成LyR7SUYZ-ZPll36wzGI5kMPamKtyXV_rN0Ax6iZG

然后是50個字符

h0UcVayzu2LyR7SUYZ-ZPll36wzGI5kMPamKtyXV_rN0Ax6iZG

碼:

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