Вместо генерации числа от 0 до 10 n -1, а затем преобразования его в строку, генерирования n чисел от 0 до 9, преобразования каждого в строку и объединения их вместе.
Отмечу, что этот метод дает числа в диапазоне (скажем, для n = 4) от 0 до 9999; Ваша оригинальная версия дает числа от 1000 до 9999. Вы можете сгенерировать первую цифру от 1 до 9 вместо 0 до 9, если хотите сохранить это свойство.
Конечно, способ, которым я это делаю, является более случайным, чем n - объединенные значения 0 - 9.
Пожалуйста, объясните, почему вы в это верите. Мне очень интересно узнать, почему люди верят в ложь.
Не могли бы вы создать Guid.NewGuid (). Tostring () и обрезать наиболее значимые символы, чтобы получить случайную строку длины N?
Вы могли бы , но вы не должны . Идентификаторы GUID не гарантируются случайными, и никакое правильное подмножество битов идентификатора GUID не может быть уникальным. Брать биты из GUID и ожидать, что биты будут иметь свойства GUID, все равно что снимать руль с самолета и ожидать, что руль полетит. Никогда и никогда не делай этого.
Скорее используйте инструменты для целей, для которых они были предназначены. GUID были разработаны для предоставления глобально уникальных идентификаторов, поэтому используйте их ни для чего другого.
Вопрос, который вы не задавали, но, вероятно, должны:
Что еще не так или подозрительно с моим кодом?
int seed = unchecked(DateTime.Now.Ticks.GetHashCode());
Что на самом деле делает этот код? Во-первых, случайный класс уже использует текущее время в качестве начального числа; это не нужно Во-вторых, какова цель выражения "1032 *" без проверки арифметики, которое не содержит арифметики ? В-третьих, зачем вы получили хеш-код? Вы не балансируете хеш-таблицу!
Random random = new Random(seed);
Если этот метод вызывается дважды в одном и том же тике, то начальное число будет одинаковым, и, следовательно, последовательность случайных чисел будет одинаковой, что означает, что вы будете потенциально долго ждать, потому что каждое сгенерированное число будет столкновение в вашем «уникальном» наборе.
Лучшей техникой является создание статического экземпляра объекта Random, посеянного один раз. Если ваша программа однопоточная, то это не проблема. Если он многопоточный, убедитесь, что у вас нет доступа к Random из нескольких потоков; это не потокобезопасно, и режим сбоя нарушения его безопасности потока не хорош.
newCode = random.Next(Convert.ToInt32(Math.Pow(10, CodeLength - 1)), Convert.ToInt32(Math.Pow(10, CodeLength) -
Действительно ли необходимо отрабатывать мощность дважды за цикл, когда она всегда одинакова? Проработайте это один раз, прежде чем начнется цикл. Код будет короче, понятнее и быстрее.
while (!ConsumerCode.isUnique(newCode));
Если коллекция заполнена, это зацикливается навсегда. Если коллекция почти заполнена, то это цикл в течение long времени. Это потенциально плохая техника для генерации уникальных случайных чисел в диапазоне. Делайте это только в том случае, если вы заранее знаете, что число сгенерированных чисел намного больше, чем максимальный размер коллекции.
Так как бы выглядел этот метод для этой функции?
Я бы хотел сделать что-то подобное. Во-первых, я хотел бы бесконечный набор цифр:
// Yield an infinite sequence of pseudo-random digits 0-9
// This method is not thread-safe.
private static Random random = new Random();
static IEnumerable<int> Digits()
{
while(true)
yield return random.Next(0, 10);
}
Теперь я могу генерировать уникальную строку цифр:
// Generates a random code of given length. If it is not
// in the set, adds it and returns the code. If it is
// already in the set, tries again.
static string AddUniqueCode(int length, HashSet<string> set)
{
while(true)
{
string code = string.Join(null, Digits().Take(length));
if (set.Add(code))
return code;
}
}
Мне нравятся мои короткие методы.
Вы также можете сделать так, чтобы метод «Цифры» использовал криптостойкость вместо псевдослучайности, если непредсказуемость важна для вас. псевдослучайные числа легко предсказать.