簡體   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