生成随机长度的GUID

alg*_*got 0 c#

我需要为自动化测试生成随机字符串.我使用以下中文自定义类来完成它.

public class UniqueIdGenerator
  {
    static public string GenerateUniqueId(int idLength)    // generates uniqueID for all fields (0-175 characters)
    {
      string uniqueID = "";
      string initialID = Guid.NewGuid().ToString().Remove(35);

      if (idLength <= 35)
      {
        uniqueID = Guid.NewGuid().ToString().Remove(idLength);
      }
      if (idLength > 35 & idLength <= 70)
      {
        uniqueID = initialID + Guid.NewGuid().ToString().Remove(idLength - 35);
      }
      if (idLength > 70 & idLength <= 105)
      {
        uniqueID = initialID + initialID + Guid.NewGuid().ToString().Remove(idLength - 70);
      }
      if (idLength > 105 & idLength <= 140)
      {
        uniqueID = initialID + initialID + initialID + Guid.NewGuid().ToString().Remove(idLength - 105);
      }
      if (idLength > 140 & idLength <= 175)
      {
        uniqueID = initialID + initialID + initialID + initialID + Guid.NewGuid().ToString().Remove(idLength - 140);
      }

      return uniqueID;
    }
Run Code Online (Sandbox Code Playgroud)

如何简化它以用于任何自然数?

Eri*_*ert 24

这是一个非常糟糕的主意,你不应该这样做.

首先,你说你需要一个随机字符串,但guid保证是唯一的,而不是随机的.Guid 可以随机生成,也可以根据当前时间生成,也可以通过为特定机器分配一系列guid然后按顺序生成它们来生成.您可以通过多种方式生成唯一标识符,其中只有一些是随机的.Guids不保证随机,所以如果你需要随机性,你使用的是错误的工具.

其次,你不能只是从一个导轨中取出部件并期望它仍然是独一无二的,不仅仅是你可以找到"飞行"的飞机部分,并期望它在没有飞机的其他部分的情况下飞行附在它上面.

如果您需要全局唯一标识符,请创建一个guid.它可能不是随机的,但它将是独一无二的.它不再需要,所以不要添加任何东西.它不能短,否则不再保证是唯一的

如果你需要一个随机字符串,那么根据需要获得随机源 - 伪随机或加密强度 - 并从你选择的字母表中生成随机字符,并将它们串在一起.您可以通过对其进行"生日问题"碰撞分析来预测其独特的可能性.一个不精确但足够接近的计算是:取字母表中可能的字符数.将其提高到弦长度的一半.这是您在生成至少一个字符串两次之前必须生成的字符串数.

例如,如果您的字母为0123456789ABCDEF,那么这是16个字符.如果字符串长度为12个字母,则计算16 6.这大约是1600万,所以你很可能在生成的前1600万个字符串中两次生成相同的字符串.


vcs*_*nes 6

如果你想要一个任意长度的随机字符串是十六进制字符,你可以使用:

    public static string GetRandomString(int length)
    {
        var rng = new RNGCryptoServiceProvider();
        var padded = (int)Math.Ceiling(length / 2.0m);
        var bytes = new byte[padded];
        rng.GetBytes(bytes);
        return bytes.Aggregate(new StringBuilder(), (f, s) => f.AppendFormat("{0:X2}", s)).ToString(0, length);
    }
Run Code Online (Sandbox Code Playgroud)


Ric*_*lly 5

请尝试以下方法:

var builder = new StringBuilder();
while(builder.Length < idLength) 
{
  builder.Append(Guid.NewGuid().ToString());
}
return builder.ToString(0, idLength);
Run Code Online (Sandbox Code Playgroud)

如果您需要的是一种能够为测试目的生成垃圾的方法,那么以下可能更合适:

private static Random Random = new Random();
public static string GenerateRandomString(int length, string characterSet = "abcdefghijklmnopqrstuvwxyzABCDDEFGHIJKLMNOPQRSTUVWXYZ")
{
    var builder = new StringBuilder();
    while(builder.Length < length) 
    {
        builder.Append(characterSet.Chars[Random.Next(characterSet.Length)]);
    }
    return builder.ToString();
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,当随机化测试值时,我更喜欢仍然给我的属性描述性名称,因为我发现失败消息通常更有帮助.我为此目的使用扩展方法:

private static Random Random = new Random();
public static string Randomise(this string value)
{
  return value + Random.Next();
}
Run Code Online (Sandbox Code Playgroud)

在我的测试中哪个是可用的,如下所示:

var customer = new Customer { Id = "CustomerId".Randomise() };
Run Code Online (Sandbox Code Playgroud)

这可能不适用于这种情况,因为需要给定长度的字符串,但是如果/当测试失败时它会节省一些时间.


Zom*_*eep 5

注意:具有用户定义长度的 GUID 不再是 GUID。

也就是说,如果您想生成一个类似于给定长度的 GUID的字符串,请尝试类似以下(未经测试的)代码。

string myMethod(int length)
{
    StringBuilder myGuidLikeString = new StringBuilder();
    while(myGuidLikeString.Length < length)
    {
        myGuidLikeString .Append(Guid.NewGuid.ToString());
    }
    return myGuidLikeString.ToString(0,length);
}
Run Code Online (Sandbox Code Playgroud)

糟糕 - rich.okelly 用几乎相同的方法打败了我。