2016-04-29 3 views
1

Этот вопрос будет главным образом основан на мнениях. Я думаю, однако, что я создал свой собственный генератор Base64 ID для столбца видимого идентификатора моих таблиц базы данных по соображениям безопасности (я увидел video о том, почему YouTube делает это и имело смысл, хотя я вижу другие способы безопасности, которые, вероятно, не так проблематичны). Он обрабатывает HIGHLY маловероятным событием, что может возникнуть дубликат, однако мне любопытно узнать, используется ли это как стандарт, например, идентификаторы видео YouTube.Генерация базы 64 ID

Program.cs

class Program 
{ 
    static void Main(string[] args) 
    { 
     var ids = new HashSet<string>(); 
     var count = 0; // for testing only 
     while (count < 8) 
     { 
      ids.Add(Base64Id.GenerateId(ids)); 
      Console.ReadLine(); 
      count++; // for testing only 
     } 
    } 
} 

Base64Id.cs

public static class Base64Id 
{ 
    private static int IdSize = 1; // Should be 11 
    private static readonly string[] AllowedChars = { 
     "0", "1", "2", "3", "4", "5", "6", "7"//, 
     //"8", "9", "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", "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", "-", "_" 
    }; 

    private static Random _random = new Random(); 

    /// <summary> 
    /// To generate a Base64 ID and check to make sure the ID is not already in use. 
    /// </summary> 
    /// <param name="usedIds">List of IDs already in use from the Database or other source.</param> 
    /// <returns>New Base64 ID</returns> 
    public static string GenerateId(HashSet<string> usedIds) 
    { 
     var autoGenId = ""; 

     do 
     { 
      autoGenId = ""; 
      for (var i = 0; i < IdSize; i++) 
       autoGenId += GetRandomChar(); 
#if DEBUG 
      _DEBUG_(usedIds.Count() + 1, autoGenId); 
#endif 
     } 
     while (IsTaken(autoGenId, usedIds)); 

     return autoGenId; 
    } 

    private static string GetRandomChar() 
    { 
     var i = _random.Next(0, AllowedChars.Length); 
     return AllowedChars[i]; 
    } 

    private static bool IsTaken(string id, HashSet<string> usedIds) 
    { 
     var check = usedIds.Any(i => id.Contains(i)); 
     if (check) 
      return true; 


     return false; 
    } 

    private static void _DEBUG_(int count, string id) 
    { 
     Console.WriteLine(String.Format("{0}:\t{1}", count, id)); 
    } 
} 

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

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

Я знаю способы исправить это, однако на шкале, которую я планирую, это безумие думать, например, иметь массив/список всех возможностей и удалять выбранный идентификатор.

Это мой вопрос;

  1. ли подобные Youtube знают об этой проблеме, и просто не все равно из-за размера возможных идентификаторов.
  2. Они просто гораздо больше думают о кладе.
  3. Они не заботятся о стоимости обработки таких высоких чисел и обрабатывают каждую мелочь.
  4. Или они используют Base64Encode в коде вместо автоматического его создания.

Я хотел бы знать ваши мнения и предложения о том, как улучшить код или если даже вопросы, которые такие огромные цифры. Я ответил тем, что, по моему мнению, может быть возможным путем его улучшения.

UPDATE

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

ответ

1

Я считаю, что для количества возможных идентификаторов, то не стоит серьезной суммы обработки для этого потребуется, чтобы убедиться, что ID уникален тем дальше он идет к концу списка, поскольку есть 73,786,976,294,838,206,464 возможности.

Скажите по десяти возможным идентификаторам 1 -> 10, если 2 уже выбраны, то в следующий раз у него есть 20% вероятность дублирования, и если 8 были выбраны, это будет 80% шанс, каждый раз. Используя вероятность, это упадет и снизит ваши шансы на получение уникального идентификатора.

Это тихое плохое, когда цифры низкие, в первый раз итераций было 14539279 и 662984 итераций, чтобы получить все 8 уникальных идентификаторов. С большими числами я знаю, что до этого момента потребуется больше времени, но это будет намного хуже.

Я думаю, что это можно разделить на двоичное дерево, когда числа станут больше, чтобы максимально использовать его, как только каждый блок, скажем, пара 100 000 или миллион, достигнет 50% или 60% использования, забудьте остальное и перейти на следующий диапазон.

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

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