Как создаются короткие имена файлов в 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 из 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 - результат (ранее -) недокументированная функция контрольной суммы.