繁体   English   中英

如何编写一个返回6个字符长度的唯一字符串的方法?

[英]How can I write a method that returns an unique string of 6 characters length?

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

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请求必须是唯一的,我怎么能基本保证...如果可能的话我不想保留一个列表并查询它...

  • 找出小于35 ^ 6(可能组合的数量)的最大素数。
  • 选择一个小于但大于一的随机数。
  • 拿(你的素数%(你的随机数*迭代指数))。 这是你的字符串的基础。
  • 在基数35中表达结果,并创建您的字符串。

这些字符串在100,000次迭代中不会重叠,因为您的随机数对于较大的数字而言相对较为重要。 不需要缓存。

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

如果随机字符串的可能长度有限,那么最简单的方法是使用GUID:

粗略的实施可能是:

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

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

不要保留所有早期值的列表。 只需使用一个柜台。

如果要使值对用户不太可预测(可猜测),请使用哈希函数在使用之前对这些位进行加扰。 但仍然从一个简单的计数器生成哈希的下一个输入。

如果使用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的下一个整数。

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

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

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

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

暂无
暂无

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

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