Як генерувати унікальні імена файлів у C #


131

Я реалізував алгоритм, який генеруватиме унікальні імена для файлів, які зберігатимуть на жорсткому диску. Я додаю DateTime: Години, Хвилини, Друга і Мілісекунди, але все ж генерує дублюючу назву файлів, оскільки я завантажую декілька файлів одночасно.

Яке найкраще рішення для створення унікальних імен для файлів, що зберігаються на жорсткому диску, щоб жодні 2 файли не були однаковими?


Це залежить від інших вимог; це [старе] питання було / занадто розпливчастим.
користувач2864740

Відповіді:


240

Якщо читабельність не має значення, використовуйте GUID .

Наприклад:

var myUniqueFileName = string.Format(@"{0}.txt", Guid.NewGuid());

або коротше :

var myUniqueFileName = $@"{Guid.NewGuid()}.txt";

У своїх програмах я іноді намагаюся, наприклад, 10 разів генерувати читабельне ім’я ("Image1.png" ... "Image10.png"), і якщо це не вдається (оскільки файл вже існує), я повертаюся до GUID.

Оновлення:

Останнім часом я також використовую DateTime.Now.Ticksзамість GUID:

var myUniqueFileName = string.Format(@"{0}.txt", DateTime.Now.Ticks);

або

var myUniqueFileName = $@"{DateTime.Now.Ticks}.txt";

Користь для мене полягає в тому, що це генерує коротше і "приємніше виглядати" ім'я файлів, порівняно з GUID.

Зверніть увагу, що в деяких випадках (наприклад, коли генерується багато випадкових імен за дуже короткий час), це може призвести до унікальних значень.

Дотримуйтесь GUID, якщо ви хочете переконатися, що імена файлів унікальні, навіть при передачі їх на інші комп'ютери.


7
Мені подобається, що використання кліщів як GUID дійсно некрасиво. Ви також можете отримати хеш тиків, що зменшує довжину символу імені файлу. DateTime.Now.Ticks.GetHashCode().ToString("x").ToUpper()
WillMcKill

4
"Кліщі" передбачувані і не є безпечними для потоків (оскільки ті ж "кліщі" можна отримати з декількох потоків / процесів). Це робить його непридатним для генерації назви файлів temp. Генерування X..1..N може бути придатним для виконання завдань, орієнтованих на користувачів (тобто копіювання в Провіднику), але є сумнівним для роботи з сервером.
користувач2864740

90

Використовуйте

Path.GetTempFileName()

або використовувати новий GUID ().

Path.GetTempFilename () на MSDN .


Ось посилання на документ MSDN: msdn.microsoft.com/en-us/library/…
epotter

3
Зауважте, що це GetTempFileName()може спричинити виняток, якщо ви створюєте багато таких файлів без їх видалення.
Джої

21
"Метод GetTempFileName підніме IOException, якщо він використовується для створення більше 65535 файлів без видалення попередніх тимчасових файлів." йдеться у статті MSDN.
Çağdaş Tekin

1
УВАГА: GetTempFileNameбуде створювати файл. Це також означає, що він обирає місце тимчасового шляху . З іншого боку, GetRandomFileNameпідходить для створення імені файлу 8.3, яке можна використовувати з іншим шляхом. (Я бачив якийсь жахливий код, який використовує GetTempFileName з File.Delete просто використовувати ім'я файлу в іншому місці.)
user2864740

77
System.IO.Path.GetRandomFileName()

Path.GetRandomFileName () на MSDN .


Ось посилання на документ MSDN: msdn.microsoft.com/en-us/library/…
epotter

13
@RyBolt: Оскільки вам не потрібно самостійно висівати, ви майже нічого не повинні пам’ятати, щоб використовувати цей метод. І я б очікував, що переважна більшість розробників не має поняття про те, як створити захищені криптографічні системи.
Джої

54

Якщо читабельність імені файлу не важлива, то це зробить GUID, як запропоновано багатьма. Однак я вважаю, що заглянути в каталог з 1000 іменами файлів GUID дуже складно розібратися. Тому я зазвичай використовую комбінацію статичної рядки, яка дає ім'я файлу деяку інформацію про контекст, часову позначку та GUID.

Наприклад:

public string GenerateFileName(string context)
{
    return context + "_" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "_" + Guid.NewGuid().ToString("N");
}

filename1 = GenerateFileName("MeasurementData");
filename2 = GenerateFileName("Image");

Таким чином, коли я сортую за назвою файлу, він автоматично групує файли за контекстним рядком і сортуватиме за часовою міткою.

Зауважте, що обмеження імені файлу у Windows становить 255 символів.


1
+1 Пропозиція включити корисну інформацію в поєднанні з GUID. - Убік взяти із собою зерно солі: включення дати та часу у назві файлу є надлишковим, коли можна просто Right Click > Sort By > Date.
Тімоті Шилдс

1
Час стає корисним, якщо ви зберігаєте купу файлів з різними контекстами в одному каталозі. Звичайно, генерацію імен файлів слід коригувати, виходячи з ваших конкретних потреб.
Мас

Повинно бути Guid.NewGuid().ToString();. Відсутня дужка. +1 в іншому випадку
Лоран В.

Це дуже гладко. Відмітка часу та керівництво. +1
JoshYates1980

Мені подобається це рішення +1, я додав розширення рядка другого параметра, яке я додаю до fileName, це додатково підтримує ідею контексту і дозволяє легко відкривати файл за допомогою програми за замовчуванням при подвійному клацанні, якщо потрібно
shelbypereira

23

Ось алгоритм, який повертає унікальне читабельне ім’я файлу на основі наданого оригіналу. Якщо існує оригінальний файл, він поступово намагається додати індекс до імені файлу, поки не знайде той, який не існує. Він зчитує наявні назви файлів у HashSet, щоб перевірити на зіткнення, тому він досить швидкий (кілька сотень назви файлів за секунду на моїй машині), він також безпечний для потоків і не страждає від перегонів.

Наприклад, якщо ви передасте його test.txt, він спробує створити файли в такому порядку:

test.txt
test (2).txt
test (3).txt

тощо. Ви можете вказати максимальні спроби або просто залишити його за замовчуванням.

Ось повний приклад:

class Program
{
    static FileStream CreateFileWithUniqueName(string folder, string fileName, 
        int maxAttempts = 1024)
    {
        // get filename base and extension
        var fileBase = Path.GetFileNameWithoutExtension(fileName);
        var ext = Path.GetExtension(fileName);
        // build hash set of filenames for performance
        var files = new HashSet<string>(Directory.GetFiles(folder));

        for (var index = 0; index < maxAttempts; index++)
        {
            // first try with the original filename, else try incrementally adding an index
            var name = (index == 0)
                ? fileName
                : String.Format("{0} ({1}){2}", fileBase, index, ext);

            // check if exists
            var fullPath = Path.Combine(folder, name);
            if(files.Contains(fullPath))
                continue;

            // try to create the file
            try
            {
                return new FileStream(fullPath, FileMode.CreateNew, FileAccess.Write);
            }
            catch (DirectoryNotFoundException) { throw; }
            catch (DriveNotFoundException) { throw; }
            catch (IOException) 
            {
                // Will occur if another thread created a file with this 
                // name since we created the HashSet. Ignore this and just
                // try with the next filename.
            } 
        }

        throw new Exception("Could not create unique filename in " + maxAttempts + " attempts");
    }

    static void Main(string[] args)
    {
        for (var i = 0; i < 500; i++)
        {
            using (var stream = CreateFileWithUniqueName(@"c:\temp\", "test.txt"))
            {
                Console.WriteLine("Created \"" + stream.Name + "\"");
            }
        }

        Console.ReadKey();
    }
}

нитка-безпечна ? неstatic readonly змінна ніlock?
Кікенет

Сам метод є статичним, тому нічого не поділяє, тому я вважаю, що кілька потоків можуть безпечно вводити цей метод одночасно. Можливо, безпечний для потоків не зовсім правильний термін - я намагаюся донести, що якщо інший потік / процес створює файл із суперечливим іменем під час виконання, то цей метод відновлює і намагається наступне доступне ім'я. Не соромтеся редагувати, якщо ви думаєте, що це можна покращити.
Майк Чемберлен

Можливо, «не страждаючи від стану перегонів» - це кращий спосіб поставити його.
Майк Чемберлен

10

Я використовую GetRandomFileName :

Метод GetRandomFileName повертає криптографічно міцну випадкову рядок, який може використовуватися як ім'я папки, так і ім'я файлу. На відміну від GetTempFileName, GetRandomFileName не створює файл. Коли безпека вашої файлової системи є першорядною, цей метод слід використовувати замість GetTempFileName.

Приклад:

public static string GenerateFileName(string extension="")
{
    return string.Concat(Path.GetRandomFileName().Replace(".", ""),
        (!string.IsNullOrEmpty(extension)) ? (extension.StartsWith(".") ? extension : string.Concat(".", extension)) : "");
}

Чи завжди метод GetRandomFileName () генерує унікальне ім'я файлу кожного разу, подібне до GUID ()?
Ашиш Шукла

1
@AshishShukla насправді я поняття не маю. msdn каже, що "генерується криптографічно сильний, випадковий рядок". У мене поки що проблем не було. Якщо унікальність критична, додаткова перевірка може стати хорошою ідеєю.
Корай

3
  1. Створіть своє ім'я файлу з часовим позначенням, виконуючи звичайний процес
  2. Перевірте, чи існує ім'я файлу
  3. Неправильно - збережіть файл
  4. Правда - додайте до файлу додатковий символ, можливо лічильник
  5. Перейдіть до кроку 2

10
Цей алгоритм є вразливим для паралельності
Jader Dias

3

Ви можете автоматично створити унікальне ім’я файлу без будь-яких спеціальних методів. Просто використовуйте наступне для класу StorageFolder або класу StorageFile . Ключовим тут є: CreationCollisionOption.GenerateUniqueNameіNameCollisionOption.GenerateUniqueName

Щоб створити новий файл з унікальним іменем файлу:

var myFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("myfile.txt", NameCollisionOption.GenerateUniqueName);

Щоб скопіювати файл у місце з унікальним іменем файлу:

var myFile2 = await myFile1.CopyAsync(ApplicationData.Current.LocalFolder, myFile1.Name, NameCollisionOption.GenerateUniqueName);

Щоб перемістити файл з унікальним іменем файлу в місці призначення:

await myFile.MoveAsync(ApplicationData.Current.LocalFolder, myFile.Name, NameCollisionOption.GenerateUniqueName);

Щоб перейменувати файл з унікальним іменем файлу у місці призначення:

await myFile.RenameAsync(myFile.Name, NameCollisionOption.GenerateUniqueName);

2

Я використовую наступний код і його добре працює. Я сподіваюся, що це може вам допомогти.

Я починаю з унікального імені файлу за допомогою часової позначки -

"контекст_" + DateTime.Now.ToString ("yyyyMMddHHmmssffff")

C # код -

public static string CreateUniqueFile(string logFilePath, string logFileName, string fileExt)
    {
        try
        {
            int fileNumber = 1;

            //prefix with . if not already provided
            fileExt = (!fileExt.StartsWith(".")) ? "." + fileExt : fileExt;

            //Generate new name
            while (File.Exists(Path.Combine(logFilePath, logFileName + "-" + fileNumber.ToString() + fileExt)))
                fileNumber++;

            //Create empty file, retry until one is created
            while (!CreateNewLogfile(logFilePath, logFileName + "-" + fileNumber.ToString() + fileExt))
                fileNumber++;

            return logFileName + "-" + fileNumber.ToString() + fileExt;
        }
        catch (Exception)
        {
            throw;
        }
    }

    private static bool CreateNewLogfile(string logFilePath, string logFile)
    {
        try
        {
            FileStream fs = new FileStream(Path.Combine(logFilePath, logFile), FileMode.CreateNew);
            fs.Close();
            return true;
        }
        catch (IOException)   //File exists, can not create new
        {
            return false;
        }
        catch (Exception)     //Exception occured
        {
            throw;
        }
    }

1

Чи потрібна штамп часу дати у назві файлу?

Ви можете зробити ім'я файлу GUID.


@downvoter Будь-яка причина для голосування "за"? GUID для імені файлів, здається, є популярною відповіддю на це питання.
Ларрі Хіпп

Це повторна відповідь, і мені не вистачає репутації, щоб зняти участь
Jader Dias

@XMLforDummies моя відповідь була однією з перших. Це може здатися не таким, як зараз, тому що воно лише показує години. Це повторна відповідь, тому що це, мабуть, правильна відповідь.
Ларрі Хіпп


1

Як щодо використання Guid.NewGuid()GUID і використовувати його як ім'я файлу (або частини імені файлу разом із тимчасовою маркою, якщо хочете).


1

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

З огляду на потрібний шлях до файлу C:\MyDir\MyFile.txt, а файл вже існує, він повертає кінцевий шлях до файлу C:\MyDir\MyFile_1.txt.

Це називається так:

var desiredPath = @"C:\MyDir\MyFile.txt";
var finalPath = UniqueFileName(desiredPath);

private static string UniqueFileName(string path, int count = 0)
{
    if (count == 0)
    {
        if (!File.Exists(path))
        {
            return path;
        }
    }
    else
    {
        var candidatePath = string.Format(
            @"{0}\{1}_{2}{3}",
            Path.GetDirectoryName(path),
            Path.GetFileNameWithoutExtension(path),
            count,
            Path.GetExtension(path));

        if (!File.Exists(candidatePath))
        {
            return candidatePath;
        }
    }

    count++;
    return UniqueFileName(path, count);
}

Це не є безпечним для потоків або безпечним для процесів. Існує умова гонки з перевіркою File.Exists і будь-яким (пізніше передбачається) створенням файлу. Тривіально, якщо викликати двічі поспіль без створення файлу, він поверне той самий результат.
користувач2864740

1

Чому ми не можемо зробити унікальний ідентифікатор, як показано нижче.

Ми можемо використовувати DateTime.Now.Ticks і Guid.NewGuid (). ToString (), щоб об’єднати разом і зробити унікальний ідентифікатор.

Як додано DateTime.Now.Ticks, ми можемо дізнатися дату та час у секундах, коли створюється унікальний ідентифікатор.

Будь ласка, дивіться код.

var ticks = DateTime.Now.Ticks;
var guid = Guid.NewGuid().ToString();
var uniqueSessionId = ticks.ToString() +'-'+ guid; //guid created by combining ticks and guid

var datetime = new DateTime(ticks);//for checking purpose
var datetimenow = DateTime.Now;    //both these date times are different.

Ми навіть можемо взяти частину кліщів в унікальному ідентифікаторі та перевірити дату та час пізніше для подальшого використання.

Ви можете долучити унікальний ідентифікатор, створений до імені файлу, або використовувати його для створення унікального ідентифікатора сеансу для входу в систему користувачів до нашого додатку чи веб-сайту.


Навіщо турбуватися з "кліщами", якщо є GUID?
користувач2864740

Під час будь-якого сценарію, якщо вам потрібно перевірити, коли генерується унікальнийSessionId, ви отримаєте точний час. А також, що конкретний кліщ з’явиться лише один раз у житті.
Джинеш Увантавіда

Тривіально, що припущення про кліщів є недійсним: 1) кілька спостерігачів можуть побачити одну і ту ж "галочку" (мислительні потоки / процеси), і 2) той самий спостерігач може спостерігатися один і той же "галочок", якщо його досить швидко запитати.
користувач2864740

Однак, по тільки з використанням Guid.NewGuid (і ігноруючи той факт , що не є «криптографически випадковим» , які можуть представляти інтерес в деяких випадках), ми можемо стверджувати , що при достатньо високій ймовірності того, що ми не дбаємо про іншому випадку, унікальний ідентифікатор буде генеруватися - це набагато, набагато вища гарантія, ніж «кліщі» . Таким чином, "тики" не мають значення / використання тут очікують, як "вторинні" дані, внесені до імені файлу.
користувач2864740

(FWIW: Я просто зафіксував якийсь код із порушеним вищезгаданим твердженням про "унікальний час" ..)
user2864740

0

Якщо ви хочете мати час, години, хвилини тощо. Ви можете використовувати статичну змінну. Додайте значення цієї змінної до імені файлу. Ви можете запустити лічильник з 0 і збільшенням, коли ви створили файл. Таким чином ім'я файлу, безумовно, буде унікальним, оскільки у вас є секунди також у файлі.


0

Я зазвичай щось роблю за цими напрямками:

  • Почніть з імені файлу стовбура ( work.dat1наприклад)
  • спробуйте створити його за допомогою CreateNew
  • якщо це працює, ви отримаєте файл, інакше ...
  • змішайте поточну дату / час із назвою файлу ( work.2011-01-15T112357.datнаприклад)
  • спробуйте створити файл
  • якщо це спрацювало, ви отримаєте файл, інакше ...
  • Змішайте монотонний лічильник у назві файлу ( work.2011-01-15T112357.0001.datнапр. (Мені не подобаються GUID. Я віддаю перевагу порядку / передбачуваності.)
  • спробуйте створити файл. Продовжуйте натискати лічильник і повторювати, поки файл не буде створений для вас.

Ось зразок класу:

static class DirectoryInfoHelpers
{
    public static FileStream CreateFileWithUniqueName( this DirectoryInfo dir , string rootName )
    {
        FileStream fs = dir.TryCreateFile( rootName ) ; // try the simple name first

        // if that didn't work, try mixing in the date/time
        if ( fs == null )
        {
            string date = DateTime.Now.ToString( "yyyy-MM-ddTHHmmss" ) ;
            string stem = Path.GetFileNameWithoutExtension(rootName) ;
            string ext  = Path.GetExtension(rootName) ?? ".dat" ;

            ext = ext.Substring(1);

            string fn = string.Format( "{0}.{1}.{2}" , stem , date , ext ) ;
            fs = dir.TryCreateFile( fn ) ;

            // if mixing in the date/time didn't work, try a sequential search
            if ( fs == null )
            {
                int seq = 0 ;
                do
                {
                    fn = string.Format( "{0}.{1}.{2:0000}.{3}" , stem , date , ++seq , ext ) ;
                    fs = dir.TryCreateFile( fn ) ;
                } while ( fs == null ) ;
            }

        }

        return fs ;
    }

    private static FileStream TryCreateFile(this DirectoryInfo dir , string fileName )
    {
        FileStream fs = null ;
        try
        {
            string fqn = Path.Combine( dir.FullName , fileName ) ;

            fs = new FileStream( fqn , FileMode.CreateNew , FileAccess.ReadWrite , FileShare.None ) ;
        }
        catch ( Exception )
        {
            fs = null ;
        }
        return fs ;
    }

}

Ви можете налаштувати алгоритм (завжди використовуйте всі можливі компоненти, наприклад, ім'я файлу). Залежить від контексту. Якщо я створив файли журналів, наприклад, щоб я міг повернутись із існування, ви б хотіли, щоб усі вони мали однакову схему з ім'ям.

Код не є ідеальним (наприклад, немає перевірок даних, переданих). І алгоритм не є ідеальним (якщо ви заповнюєте жорсткий диск або стикаєтесь з дозволами, фактичними помилками вводу / виводу або іншими помилками файлової системи, наприклад, він буде зависати, як це є, у нескінченному циклі).


0

Я закінчую об'єднання GUID з Днем Місяць Рік Друга Мілісекунда, і я думаю, що це рішення є досить хорошим у моєму сценарії


0

ви можете використовувати Random.Next () також для створення випадкового числа. ви можете побачити посилання MSDN: http://msdn.microsoft.com/en-us/library/9b3ta19y.aspx


2
Я б не рекомендував цього, оскільки це не потрібно бути випадковим. Це має бути унікальним.
Макс

0

Я написав клас спеціально для цього. Він ініціалізується "базовою" частиною (за замовчуванням до точної хвилинної позначки) і після цього додає літери, щоб зробити унікальні імена. Отже, якщо перша генерована марка - 1907101215a, друга - 1907101215b, то 1907101215c, et cetera.

Якщо мені потрібно більше 25 унікальних марок, то я використовую unry 'z, щоб рахувати 25. Отже, це іде 1907101215y, 1907101215za, 1907101215zb, ... 1907101215zy, 1907101215zza, 1907101215zzb тощо. Це гарантує, що марки завжди будуть сортуватися буквено-цифровими у порядку, в якому вони були створені (доки наступний символ після штампу не буде літерою).

Це не безпечно для потоків, не оновлює час автоматично і швидко розквітає, якщо вам потрібні сотні марок, але я вважаю це достатнім для моїх потреб.

/// <summary>
/// Class for generating unique stamps (for filenames, etc.)
/// </summary>
/// <remarks>
/// Each time ToString() is called, a unique stamp is generated.
/// Stamps are guaranteed to sort alphanumerically in order of generation.
/// </remarks>
public class StampGenerator
{
  /// <summary>
  /// All the characters which could be the last character in the stamp.
  /// </summary>
  private static readonly char[] _trailingChars =
  {
    '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'
  };

  /// <summary>
  /// How many valid trailing characters there are.
  /// </summary>
  /// <remarks>Should always equal _trailingChars.Length</remarks>
  public const int TRAILING_RANGE = 25;

  /// <summary>
  /// Maximum length of the stamp. Hard-coded for laziness.
  /// </summary>
  public const int MAX_LENGTH_STAMP = 28;

  /// <summary>
  /// Base portion of the stamp. Will be constant between calls.
  /// </summary>
  /// <remarks>
  /// This is intended to uniquely distinguish between instances.
  /// Default behavior is to generate a minute-accurate timestamp.
  /// </remarks>
  public string StampBase { get; }

  /// <summary>
  /// Number of times this instance has been called.
  /// </summary>
  public int CalledTimes { get; private set; }

  /// <summary>
  /// Maximum number of stamps that can be generated with a given base.
  /// </summary>
  public int MaxCalls { get; }

  /// <summary>
  /// Number of stamps remaining for this instance.
  /// </summary>
  public int RemainingCalls { get { return MaxCalls - CalledTimes; } }

  /// <summary>
  /// Instantiate a StampGenerator with a specific base.
  /// </summary>
  /// <param name="stampBase">Base of stamp.</param>
  /// <param name="calledTimes">
  /// Number of times this base has already been used.
  /// </param>
  public StampGenerator(string stampBase, int calledTimes = 0)
  {
    if (stampBase == null)
    {
      throw new ArgumentNullException("stampBase");
    }
    else if (Regex.IsMatch(stampBase, "[^a-zA-Z_0-9 \\-]"))
    {
      throw new ArgumentException("Invalid characters in Stamp Base.",
                                  "stampBase");
    }
    else if (stampBase.Length >= MAX_LENGTH_STAMP - 1)
    {
      throw new ArgumentException(
        string.Format("Stamp Base too long. (Length {0} out of {1})",
                      stampBase.Length, MAX_LENGTH_STAMP - 1), "stampBase");
    }
    else if (calledTimes < 0)
    {
      throw new ArgumentOutOfRangeException(
        "calledTimes", calledTimes, "calledTimes cannot be negative.");
    }
    else
    {
      int maxCalls = TRAILING_RANGE * (MAX_LENGTH_STAMP - stampBase.Length);
      if (calledTimes >= maxCalls)
      {
        throw new ArgumentOutOfRangeException(
          "calledTimes", calledTimes, string.Format(
            "Called Times too large; max for stem of length {0} is {1}.",
            stampBase.Length, maxCalls));
      }
      else
      {
        StampBase = stampBase;
        CalledTimes = calledTimes;
        MaxCalls = maxCalls;
      }
    }
  }

  /// <summary>
  /// Instantiate a StampGenerator with default base string based on time.
  /// </summary>
  public StampGenerator() : this(DateTime.Now.ToString("yMMddHHmm")) { }

  /// <summary>
  /// Generate a unique stamp.
  /// </summary>
  /// <remarks>
  /// Stamp values are orered like this:
  /// a, b, ... x, y, za, zb, ... zx, zy, zza, zzb, ...
  /// </remarks>
  /// <returns>A unique stamp.</returns>
  public override string ToString()
  {
    int zCount = CalledTimes / TRAILING_RANGE;
    int trailing = CalledTimes % TRAILING_RANGE;
    int length = StampBase.Length + zCount + 1;

    if (length > MAX_LENGTH_STAMP)
    {
      throw new InvalidOperationException(
        "Stamp length overflown! Cannot generate new stamps.");
    }
    else
    {
      CalledTimes = CalledTimes + 1;
      var builder = new StringBuilder(StampBase, length);
      builder.Append('z', zCount);
      builder.Append(_trailingChars[trailing]);
      return builder.ToString();
    }
  }
}

-1

DateTime.Now.Ticksне є безпечним, Guid.NewGuid()занадто потворним, якщо вам потрібно щось чисте і майже безпечне ( це не 100% безпечно, наприклад, якщо ви називаєте це 1 000 000 разів за 1 мс ), спробуйте:

Math.Abs(Guid.NewGuid().GetHashCode())

Під безпечним я маю на увазі, що безпека є унікальною, коли ви її зателефонуєте так багато разів за дуже короткий проміжок часу за кілька мс часу.


Чи є якісь проблеми з моїм рішенням downvoter? будь ласка, дай мені знати.
Мехді Дехгані

GetHashCodeМетод повертає int, який має 32-бітний діапазон, в той час як GUIDмає 128-бітний діапазон, і тому набагато більше шансів бути унікальним. Якщо формат GUIDзначення вам не подобається , просто зателефонуйте ToString("N")на нього, що видалить тире.
4thex
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.