Member 10947681 Ответов: 3

Как генерирует N нет 6-ти значный уникальный ключ (дубликат) на C# в ASP.NET


Хии,
Я хочу сгенерировать N no из 6-значной уникальной строки(буквенно-цифровой), которую я попробовал ниже, но получил так много дубликатов значения, пожалуйста, кто-нибудь может мне помочь ????

Что я уже пробовал:

public static string GetUniqueKey(int maxSize)
        {
            char[] chars = new char[62];
            chars =
            "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray();
            byte[] data = new byte[1];
            using (RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider())
            {
                crypto.GetNonZeroBytes(data);
                data = new byte[maxSize];
                crypto.GetNonZeroBytes(data);
            }
            StringBuilder result = new StringBuilder(maxSize);
            foreach (byte b in data)
            {
                result.Append(chars[b % (chars.Length)]);
            }
            return result.ToString();
        }

On Button Click ----
   for (int i = 0; i < LEN; i++)
             {
                
                 dt_Output.Rows.Add(GetUniqueKey(6));

                
             }

             System.Data.DataSet ds = new System.Data.DataSet();
             ds.Tables.Add(dt_Output);

BillWoodruff

Предположим, что вы получили этот код из статьи CodeProject Айтала Аль-Амина: когда вы публикуете код, который не является "оригинальным", неплохо дать ссылку на то, откуда он взялся. Нет ничего "плохого" в повторном использовании кода, но это может помочь нам ответить на ваш вопрос, если мы сможем сравнить ваш код с его источником.

Не могли бы вы использовать Int32 или Int64 для идентификационного кода строк в базе данных ?

Что привело вас к решению использовать RNGCryptoServiceProvider здесь: почему случайные числа не работают для вас ?

3 Ответов

Рейтинг:
4

athar13

OrginalGriff очень хорошо ответил на ваш вопрос.

Вам придется использовать хэш-таблицу, или ArrayList, или List<string>. Что бы ни было сгенерировано, проверьте, существует ли оно в списке "строка", прежде чем добавлять его. Продолжайте делать это до тех пор, пока длина списка "строка" не совпадет с требуемым количеством.

Вам придется изменить for () На a while (), и это может занять некоторое время для большего maxSize.


Рейтинг:
27

OriginalGriff

Существует два способа создания гарантированных уникальных ключей:
1) постепенно, так что ключ (N + 1) является фиксированной величиной, большей, чем ключ(N) - обычно один.
2) просматривая все текущие сгенерированные значения и проверяя, что вы не повторили.

Первый вариант предполагает поддержание (обычно потокобезопасного) счетчика "следующего значения" и его увеличение сразу же после его использования.
Второй способ-вести список "выданных" номеров и проверять каждый раз, когда вы пытаетесь выделить новый, чтобы убедиться, что он еще не существует.

Случайные числа не гарантированно уникальны - даже GUID не уникальны, просто фазовое пространство, из которого они взяты, настолько велико, что феноменально маловероятно, что вы повторите это в течение нормальной жизни.


Member 10947681

Спасибо за ваш ответ не могли бы вы предоставить мне пример кода для
2) просматривая все текущие сгенерированные значения и проверяя, что вы не повторили.

OriginalGriff

Попробуйте заглянуть в словарь - он использует внутреннюю хэш-таблицу, поэтому поиск происходит довольно быстро, и он является универсальным, что делает ваш код чище.
Возможно, вам стоит также взглянуть на StringDictionary - он оптимизирован для строковых ключей, так что это может быть лучшим выбором, если ваш список станет действительно большим.
Документация MSDN для этих двух классов включает примеры.

BillWoodruff

Очень интересное предложение, за которым я последую с помощью временного эксперимента по сравнению с тем, что я использую сейчас для генерации строк фиксированной длины.

OriginalGriff

Интересно: я только что это сделал, и это очень медленно.
В десятикратном тесте с 9804 строками (каждая из которых представляет собой одну строку из Хроник Нарнии) использование "оптимизированного" StringDictionary примерно в 5 раз медленнее, чем общего словаря - вероятно, из-за "строчных и культурных инвариантных" сравнений.

Оптимизирован он может быть, но быстрее-нет! :смеяться:

BillWoodruff

Если бы ОП здесь ответил на мои вопросы, я бы опубликовал какой-нибудь код. Держу пари, вы знакомы с экспериментами Джеффа Этвуда по кодированию базы более высокого порядка для повышения читабельности и / или более поздним сообщением Рика Страла в блоге ? Ссылки по запросу.

В своем коде я использую цикл while-loop, чтобы продолжать выкашливать новые потенциальные идентификаторы до тех пор, пока не сгенерирую их столько, сколько указано. Интересно, что использование ' Contains для проверки того, есть ли данный идентификатор уже в коллекции, на много порядков быстрее, чем использование 'Any.

Рейтинг:
1

Patrice T

Цитата:
Как создать N no 6-значного уникального ключа (без дубликата)

Вам нужна процедура в 2 шага
- вам нужно управлять счетчиком, у которого есть задача выдавать уникальные значения. Это единственный практический способ обеспечить множество уникальных ключей в течение длительного периода времени.
- Тогда вам нужна функция, которая будет кодировать это значение в базе 62.
Функция base962 может выглядеть примерно так:
public static string ToBase62(int Value, int Digits)
{
    char[] chars = new char[62];
    chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray();
    
    if (Digits==0) return"";
    return ToBase62(Value/(chars.Length), Digits-1).Append(chars[Value % (chars.Length)]);
}


BillWoodruff

- Тогда вам нужна функция, которая закодирует это значение в базе 62."

Почему?

Patrice T

Функция облегчает проверку этой функции.
Это классическое базовое преобразование, и функцию, выполняющую его, легко найти.

BillWoodruff

Подумайте на минуту о том, что кто-то относительно новичок в .NET читает ваш ответ.

BillWoodruff

Мой голос №1: первая часть этого решения уже была опубликована, когда это было опубликовано, а вторая часть этого решения необъяснима и, скорее всего, сбивает с толку ОП или кого-либо еще, кто не знаком с причинами использования базового кодирования более высокого порядка.

Patrice T

Теперь тебе больше нравится?

BillWoodruff

Да, так лучше. :) И я изменил свой голос на № 3 ... что, кстати, я не считаю отрицательным голосованием. Если бы ваш пост был первым, в котором упоминалось ваше первое предложение, я бы проголосовал за № 4. И позвольте мне предложить вам добавить комментарий о том, почему вам "нужна" базовая функция кодирования; я знаю, почему она полезна, но подозреваю, что ОП этого не делает.

твое здоровье, Билл

Patrice T

Голос № 3 со временем менялся между отрицательным и нейтральным, к сожалению, на самом деле он отрицательный.