Как создаются короткие имена файлов в Windows?

В настоящее время я использую следующую подпись P/Invoke, чтобы получить краткое имя обычного файла Windows:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetShortPathName([MarshalAs(UnmanagedType.LPTStr)] string path,
                                          [MarshalAs(UnmanagedType.LPTStr)] StringBuilder shortPath,
                                          int shortPathLength);

На данный момент - работает без проблем, но заметил кое-что довольно своеобразное:
Я знаю, что Windows использует следующее соглашение коротких имен файлов:

Сократить имя до 6 символов (без расширения)
Добавить тильду (~)
Добавьте целое число без знака, которое указывает индекс соответствия (начиная с 1)
Добавить исходное расширение файла

Таким образом, имя файла C:\abcdefghijklmn.txt должен быть доступен под коротким именем C:\abcdefg~1.txt, (Который работает отлично.)

Теперь странная часть: я недавно выполнил небольшой поиск в моем музыкальном каталоге для определенных аудиофайлов. Это был результат:

.\Rammstein & Tatu - Moscow.mp3
.\Rammstein - Asche zu Asche.mp3
.\Rammstein - Der Meister.mp3
.\Rammstein - Du Hast.mp3
.\Rammstein - Eifersucht.mp3
.\Rammstein - Feuer Frei.mp3
.\Rammstein - Führe Mich.mp3
.\Rammstein - Haifisch.mp3
...

И тот же поиск в краткой записи:

.\RA8E17~1.MP3
.\RA23A6~1.MP3
.\RAMMST~1.MP3
.\RA0CAE~1.MP3
.\RAMMST~2.MP3
.\RAMMST~3.MP3
.\RAMMST~4.MP3
.\RA6BAA~1.MP3
...

Мой вопрос: почему окна генерируют такие "случайные" префиксы до тильды (например, RA23A6 или же RA0CAE)?

2 ответа

Решение

Microsoft не документирует это, но Википедия:

8.3 имя файла:

Хотя нет обязательного алгоритма для создания имени 8.3 из LFN, Windows использует следующее соглашение:

1.Если LFN указан в верхнем регистре 8,3, то LFN не будет храниться на диске вообще.

  • Пример: TEXTFILE.TXT

2. Если LFN является смешанным регистром 8.3, LFN будет хранить имя смешанного регистра, тогда как имя 8.3 будет его версией в верхнем регистре.

  • Пример: TextFile.Txt становится TEXTFILE.TXT,

3.Если имя файла содержит символы, недопустимые в имени 8.3 (включая пробел, запрещенный соглашением, но не API-интерфейсами), или какая-либо часть является слишком длинной, имя удаляется из недопустимых символов, таких как пробелы и дополнительные точки. Другие персонажи, такие как + изменены на подчеркивание _ и в верхнем регистре. Затем раздетое имя усекается до первых 6 букв его базового имени, за которым следует тильда, затем одна цифра и точка. . Далее следуют первые 3 символа расширения.

  • Пример: TextFile1.Mine.txt становится TEXTFI~1.TXT (или же TEXTFI~2.TXT, должен TEXTFI~1.TXT уже существует). ver +1.2.text становится VER_12~1.TEX,

4. Начиная с Windows 2000, если по крайней мере 4 файла или папки уже существуют с одинаковыми начальными 6 символами в их коротких именах, выделенный LFN вместо этого усекается до первых 2 букв базового имени (или 1, если базовое имя имеет только 1 буква), за которой следуют 4 шестнадцатеричные цифры, полученные из недокументированного хэша имени файла, за которым следует тильда, затем одна цифра и точка . Далее следуют первые 3 символа расширения.

  • Пример: TextFile.Mine.txt становится TE021F~1.TXT,

Как упоминал Джои, недокументированный хэш имени файла был переработан.

Это потому, что очень примитивная схема использования счетчика и префикса работает только до определенного количества файлов. С увеличением количества файлов Windows переключается на более короткий префикс и хэш. Кто-то на самом деле перепроектировал хеш вместе с небольшим объяснением:

Если вы не знаете, как работают имена файлов 8.3, вот краткий обзор.

  • Все периоды, кроме того, который отделяет имя файла от расширения, удаляются - a.testing.file.bat превращается в atestingfile.bat.
  • Некоторые специальные символы, такие как +, превращаются в подчеркивания, а другие отбрасываются. Имя файла в верхнем регистре. 1+2+3 Hello World.exe превращается в 1_2_3HELLOWORLD.EXE.
  • Расширение файла усекается до 3 символов, и (если длиннее 8 символов) имя файла усекается до 6 символов, за которыми следует ~1. SomeStuff.aspx превращается в SOMEST~1.ASP.
  • Если это вызовет столкновение, вместо него используется ~2, а затем ~3 и ~4.
  • Вместо перехода к ~5 имя файла усекается до 2 символов, а заменяемая заменяется шестнадцатеричной контрольной суммой длинного имени файла - SomeStuff.aspx превращается в SOBC84~1.ASP, где BC84 - результат (ранее -) недокументированная функция контрольной суммы.
Другие вопросы по тегам