2011-11-30 3 views
3

Если я это сделать, как это я получаю некоторые дубликаты ...Как написать метод, который возвращает уникальную строку длиной в 6 символов?

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 должен быть уникальным, как я могу гарантировать это в основном ... , если это возможно, я не хочу, чтобы сохранить список и запросить его ...

+7

вы не можете без кэширования его. это особенность случайности. –

+0

@ DanielA.White - Разве вы не имеете в виду ... * надевает солнцезащитные очки * ... случайную вещь о случайности? – Polynomial

+0

Вы хотите что-то уникальное или случайное? Они очень разные. – Sign

ответ

0

Если возможная длина случайной строки ограничена, было бы проще всего использовать GUIDs:

сырой реализации может быть:

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

Если вам нужно больше времени, вы можете объединить несколько строк GUID вместе.

+7

Приставки подстроки GUID невероятно не уникальны –

+0

Хорошая точка - ее общая строка, которая уникальна, не так ли. Можете ли вы представить себе способ захвата этого? Было бы достаточно взять последние n символов вместо первого n? –

+2

GUID не уникальны. Диапазон возможных значений настолько велик, что вряд ли он будет получать одно и то же значение дважды при случайном выборе двух значений. – dtb

0

Не сохраняйте список всех предыдущих значений. Просто используйте счетчик.

Если вы хотите сделать значение менее предсказуемым (допустимым) для пользователя, используйте хэш-функцию для скремблирования бит перед их использованием. Но все же сгенерируйте следующий вход в хэш из простого счетчика.

+0

это звучит неплохо ... Я посмотрю на Interlocked first ... Тогда, вероятно, Hash значение счетчика ... – Serdar

2
  • Рисунок наибольшего числа, которое меньше 35^6 (количество возможных комбинаций).
  • Выберите случайное число, меньшее этого, но больше одного.
  • Возьмите (ваш основной% (ваш случайный номер * итерационный индекс)). Это то, из чего вы основываете свою строку.
  • Выведите результат в основании 35 и создайте свою строку.

Эти строки не будут перекрывать более 100 000 итераций, потому что ваше случайное число относительно простое для большего числа. Не требуется кэширование.

Перед записью строк вы можете запустить случайное число итераций, чтобы получить большее пространство результатов.

+0

Звучит неплохо, но это не работает. Проверьте алгоритм, но я думаю, что у вас есть неверное предположение о том, что относительная привилегия покупает вас. –

0

Если вы использовали int для представления разрядных позиций, вы могли бы сделать это легко.

int bits=0 

... 

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

Теперь вы знаете, у вас есть 6 битов в ИНТ, поэтому конвертировать их в строку

Например с данными:

"ABCDEFGHIJKLMNOPQRSTUVWXYZ123654987" 

, если вы рассчитывали и достигли 111111, (Первый из них вы ударите), вы вернетесь «234567», следующий, я считаю, будет 1011111, который вернет «134567», затем «1101111», который вернет «124567». (Я мог бы получить последовательность неправильно, это просто с моей головы).

Он всегда будет уникальным, и повторение не так дорого, как вы думаете, хотя вы, вероятно, могли бы быть немного умнее, чем просто повторять (вы могли бы пропустить большие группы, если бы поняли, что математически невозможно достигнуть следующего 6-дюймового номера бит до n приращений, или вы можете просто придумать более прямой алгоритм для генерации следующего целого числа с 6 1.

0

Возможно, вы можете использовать текущую метку времени (миллисекунды, микросекунды или nannoseconds) (отмените ее или измените порядок цифр, если вам нужно показать случайность) и замените цифры в номере метки меткой AZ и 0-9 символов по некоторым критериям.

В противном случае, если у вас нет механизма кэширования, хранящегося ранее сгенерированных значений, я думаю, вы не можете получить случайные и УНИКАЛЬНЫЕ последовательности символов.

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

большое спасибо ... но мне также нужна какая-то случайность ... строки должны быть неопределенными ... Думаю, я буду использовать временные интервалы и что-то смешать с ним. – Serdar

Смежные вопросы