简体   繁体   English

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

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

If I do it like this I get some duplicates... 如果我这样做,我会得到一些重复...

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

The first 100000 request must be unique how can I guarantee it basically... if possible I do not want to keep a list and query it... 第一个100000请求必须是唯一的,我怎么能基本保证...如果可能的话我不想保留一个列表并查询它...

  • Figure out the largest prime that's less than 35^6 (the number of possible combinations). 找出小于35 ^ 6(可能组合的数量)的最大素数。
  • Choose a random number that's less than that but greater than one. 选择一个小于但大于一的随机数。
  • Take (your prime % (your random number * iteration index)). 拿(你的素数%(你的随机数*迭代指数))。 This is what you base your string from. 这是你的字符串的基础。
  • Express the result in base 35, and create your string. 在基数35中表达结果,并创建您的字符串。

These strings won't overlap over 100,000 iterations because your random number is relatively prime to the larger number. 这些字符串在100,000次迭代中不会重叠,因为您的随机数对于较大的数字而言相对较为重要。 No caching needed. 不需要缓存。

You can run through a random number of iterations before recording the strings to give yourself a larger result space. 在记录字符串之前,您可以运行随机数量的迭代,从而为自己提供更大的结果空间。

If your possible length of random string is limited it would be easiest to use GUIDs: 如果随机字符串的可能长度有限,那么最简单的方法是使用GUID:

A crude implementation might be: 粗略的实施可能是:

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

If you need longer then you could concatenate multiple GUID strings together. 如果需要更长时间,则可以将多个GUID字符串连接在一起。

Don't keep a list of all earlier values. 不要保留所有早期值的列表。 Just use a counter. 只需使用一个柜台。

If you want to make the value less predictable (guessable) to a user, use a hash function to scramble the bits before using them. 如果要使值对用户不太可预测(可猜测),请使用哈希函数在使用之前对这些位进行加扰。 But still generate the next input to the hash from a simple counter. 但仍然从一个简单的计数器生成哈希的下一个输入。

If you used an int to represent bit positions, you could do it easily. 如果使用int来表示位位置,则可以轻松完成。

int bits=0

...

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

Now you know you have 6 bits in your int, so convert them to the string 现在您知道int中有6位,因此将它们转换为字符串

For instance with your data: 例如,您的数据:

"ABCDEFGHIJKLMNOPQRSTUVWXYZ123654987"

if you were counting and had reached 111111, (The first one you will hit) you'd return "234567", the next one I believe will be 1011111 which will return "134567" then "1101111" which will return "124567". 如果你正在计算并且已达到111111,(你将击中的第一个)你将返回“234567”,我认为下一个将是1011111,它将返回“134567”然后“1101111”将返回“124567”。 (I could be getting the sequence wrong, it's just off the top of my head). (我可能会把序列弄错,它只是在我的头顶)。

It will always be unique, and the iterating isn't as expensive as you'd think, although you could probably be a bit smarter than just iterating (you could skip large groups if you figured out it was mathematically impossible to reach the next 6-"on" bit number before n increments, or you could just come up with a more straight-forward algorithm to generate the next integer with 6 1's. 它总是独一无二的,并且迭代并不像你想象的那么昂贵,尽管你可能比仅仅迭代更聪明(如果你发现它在数学上不可能达到下一个6,你可以跳过大组) - 在n增量之前的“on”位数,或者你可以想出一个更直接的算法来生成6 1的下一个整数。

You may be able to use current time stamp (milliseconds, microseconds or nannoseconds) (reverse it or change the digit order if you need to show a randomness) and replace the digits in the timestamp number with AZ and 0-9 characters on some criteria. 您可以使用当前时间戳(毫秒,微秒或纳秒)(如果需要显示随机性,则将其反转或更改数字顺序)并在某些条件下将时间戳编号中的数字替换为AZ和0-9个字符。

Otherwise If you don't have any caching mechanism store previously generated values, I think you cannot get random and UNIQUE character sequences. 否则如果您没有任何缓存机制存储以前生成的值,我认为您无法获得随机和UNIQUE字符序列。

If they don't need to be random but only unique then this code works using an odometer type of output. 如果它们不需要是随机的但只是唯一的,则此代码使用里程表类型的输出。

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

And here is a passing unit test, but it takes a long time to run... 这是一个通过单元测试,但运行需要很长时间...

[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.

相关问题 如何将字符串的长度限制为 150 个字符? - How can I limit the length of a string to 150 characters? 如何编写返回 xaml 切换开关的值的方法? - How can I write a method that returns the value of a of xaml toggle switch? 如果字符串的长度小于15,如何获取字符串的前15个字符或更少的字符? - How can I get the first 15 characters of a string or less if the string is less than 15 in length? 如何编写一种以列表结构从Matisse表返回所有记录的方法? - How can I write a method that returns all records from a Matisse table in a list structure? 如何从字符串中提取唯一字符? - How do I extract unique characters from a string? 如何编写同时包含字符串和双精度类型的方法? 应该是void还是返回类型方法? - How can i write a method that contains both string and double type? should it be a void or return type method? 如何为字符串生成唯一的哈希码 - How can I generate a unique hashcode for a string 如何在C#中创建一个独特的随机字符序列? - How can I create an unique random sequence of characters in C#? 我如何检查字符串以查看所有字符是否都是整数,长度为 8 个字符并为每个字符抛出一个参数? - How do i check string to see if all characters are integers, that it is 8 characters in length and throw an argument for each? 如何在字符串中使用占位符? - How can I use placeholders for characters in a string?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM