例如:AB5C8A~1
据我了解,前两个字符来自常规文件名。有人可以指导我了解 DOS 如何确定第三到第六个字符的数学原理吗?
从wiki来看,没有强制算法从长文件名创建 8.3 名称,但他们确实尝试遵循约定。使用您示例中的文件名,它似乎使用选项 4,其中使用文件名的哈希来生成 4 个十六进制数字
我找到了一些代码,但我不知道它是否与微软使用的相同......
从这个网站获得许可
所有(一些?)源可用于他们的系统在这里
/* msdos_short_hex_number --
* Routine to set the hex number in the SFN.
*
* PARAMETERS:
* name - name to change
* num - number to set
*
* RETURNS:
* nothing
*
*/
static void
msdos_short_name_hex(char* sfn, int num)
{
static const char* hex = "0123456789ABCDEF";
char* c = MSDOS_DIR_NAME(sfn);
int i;
for (i = 0; i < 2; i++, c++)
if ((*c == ' ') || (*c == '.'))
*c = '_';
for (i = 0; i < 4; i++, c++)
*c = hex[(num >> ((3 - i) * 4)) & 0xf];
*c++ = '~';
*c++ = '1';
}
Sean Cheshire 在他的回答中提供了很好的参考。但这些规则只是部分记录在案。
即使记录了完整的算法,我也不知道如何在不知道包含文件夹的完整历史记录的情况下可靠地预测给定文件的 8.3 名称。分配的名称可能会有所不同,具体取决于创建之前同一文件夹中存在多少类似名称的文件。
获取 8.3 名称的唯一可靠方法是查询目录。
最简单的方法是使用/x
DIR 命令的选项,但是那个输出不方便解析。
将 8.3 名称放入变量的最简单方法是将~s
修饰符与 FOR 变量或 CALL 参数一起使用。
for %%F in ("long file name.ext") do set "shortName=%~sF"
或者
call :getShort "long file name.ext"
exit /b
:getShort
set "shortName=%~s1"
exit /b
注意 - 使用 FOR 而不是 CALL 更快
8.3 名称也可通过 WMIC DATAFILE 别名获得。