3

如果我这样做,我会得到一些重复...

private const string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123654987";

public string RandomString(int size)
{
    var random = new Random((int)DateTime.Now.Ticks);
    Thread.Sleep(random.Next(1, 3));

    var buffer = new char[size];

    for (int i = 0; i < size; i++)
    {
        buffer[i] = _chars[random.Next(_chars.Length)];
    }
    return new string(buffer);
}

第一个100000请求必须是唯一的我怎么能保证它基本上......如果可能的话我不想保留一个列表并查询它......

4

6 回答 6

2
  • 找出小于 35^6(可能组合的数量)的最大素数。
  • 选择一个小于该值但大于一的随机数。
  • 取(你的素数百分比(你的随机数 * 迭代索引))。这就是你的字符串的基础。
  • 以 35 为基数表示结果,并创建您的字符串。

这些字符串不会重叠超过 100,000 次迭代,因为您的随机数与较大的数相对质数。不需要缓存。

您可以在记录字符串之前运行随机次数的迭代,从而为自己提供更大的结果空间。

于 2011-11-30T16:57:09.327 回答
0

如果您可能的随机字符串长度有限,则最容易使用 GUID:

粗略的实现可能是:

    public string RandomString(int size)
    {
        return Guid.NewGuid()
            .ToString()
            .Replace("-","")
            .Substring(0, size);
    }

如果您需要更长的时间,则可以将多个 GUID 字符串连接在一起。

于 2011-11-30T16:50:20.813 回答
0

您可能可以使用当前时间戳(毫秒、微秒或纳秒)(如果需要显示随机性,请反转它或更改数字顺序)并在某些条件下用 AZ 和 0-9 字符替换时间戳编号中的数字.

否则,如果您没有任何缓存机制存储以前生成的值,我认为您无法获得随机和唯一的字符序列。

于 2011-11-30T17:03:27.350 回答
0

不要保留所有早期值的列表。只需使用计数器。

如果您想让该值对用户来说更难以预测(可猜测),请在使用之前使用散列函数对位进行加扰。但仍然从一个简单的计数器生成哈希的下一个输入。

于 2011-11-30T16:52:48.563 回答
0

如果您使用 int 来表示位位置,则可以轻松完成。

int bits=0

...

while(bitCount(bits)!=6) // Write your own bitCount method--or there is probably one on the net
    bits++;

现在您知道 int 中有 6 位,因此将它们转换为字符串

例如,您的数据:

"ABCDEFGHIJKLMNOPQRSTUVWXYZ123654987"

如果您正在计数并已达到 111111,(您将击中的第一个)您将返回“234567”,我相信下一个将是 1011111,它将返回“134567”,然后是“1101111”,它将返回“124567”。(我可能弄错了顺序,这只是我的想法)。

它总是独一无二的,并且迭代并不像你想象的那么昂贵,尽管你可能比仅仅迭代更聪明一点(如果你发现在数学上不可能达到下一个 6,你可以跳过大组- n 递增之前的“on”位数,或者您可以提出一个更直接的算法来生成下一个带有 6 个 1 的整数。

于 2011-11-30T16:57:49.563 回答
0

如果它们不需要是随机的而只是唯一的,那么此代码使用里程表类型的输出工作。

public class Class1
{
    List<char> _chars = new List<char>() { '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', '1', '2','3','4', '5', '6', '7', '8', '9', '0' };
    private static int[] index = new int[6] {0, 0, 0, 0, 0, 0};
    private const int charMax = 35;

    public string UniqueString()
    {
        if (index[5] > charMax)
        {
            IncromentParent(5);
        }

        StringBuilder result = new StringBuilder();
        result.Append(_chars[index[0]]);
        result.Append(_chars[index[1]]);
        result.Append(_chars[index[2]]);
        result.Append(_chars[index[3]]);
        result.Append(_chars[index[4]]);
        result.Append(_chars[index[5]]);

        index[5]++;
        return result.ToString();
    }

    private void IncromentParent(int active)
    {
        if (active == 0)
            throw new Exception("out of numbers");

        int parent = active - 1;
        index[active] = 0;
        index[parent]++;
        if (index[parent] > charMax)
            IncromentParent(parent);
    } 
}

而且这里是一个通过的单元测试,但是运行起来需要很长时间...

[TestMethod]
public void MyTestMethod()
{
    Class1 target = new Class1();
    List<string> results = new List<string>();

    for (int i = 0; i < 100000; i++)
    {            
        string result = target.UniqueString();

        if (!results.Contains(result))
            results.Add(result);
        else
            Assert.Fail(string.Format("The string '{0}' is already in the list", result));
    }
   Console.WriteLine(results.Count.ToString());
}
于 2011-11-30T19:58:17.607 回答