gpt4 book ai didi

c# - 验证 .vhd 文件实际上是 vhd

转载 作者:行者123 更新时间:2023-12-03 07:48:30 27 4
gpt4 key购买 nike

用户可以将 vhd 文件上传到我的服务器。我想验证他们上传的文件,并确保它们实际上是有效的 vhd 文件,而不是使用 .vhd 文件扩展名等重新命名的 jpeg 文件。有没有办法做到这一点?

最佳答案

https://www.garykessler.net/library/file_sigs.html (Ctrl + F,然后输入 VHD)

VHD 文件的前 8 个字节如下:63 6F 6E 65 63 74 69 78(ASCII 格式的 conectix)

根据 @jdweng 在评论部分的建议,您也许可以使用 BinaryReader读取前8个字节并与上面的值进行比较,以确定该文件是否为VHD文件。

编辑:不起作用,正在寻找其他解决方案。

编辑2:实际上,文本conectix确实存在于文件中,但它不在文件的开头;文本位于[文件末尾] - 0x200第一个字节。现在就去测试一下。仅供引用,该文件是使用 Windows 10 上的磁盘管理工具生成的。

编辑3:

private static bool IsVhd(string path)
{
byte[] vhdHeader = { 0x63, 0x6F, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x78 };
byte[] header;

FileInfo file = new FileInfo(path);
long length = file.Length;

using (BinaryReader br = new BinaryReader(file.OpenRead()))
{
br.BaseStream.Position = length - 0x200; //Where the "conectix" is located at
header = br.ReadBytes(8);
}

return vhdHeader.SequenceEqual(header);
}

我相信这样就可以了。

编辑4:

private static bool IsVhd(string path)
{
Span<byte> vhdHeader = stackalloc byte[] { 0x63, 0x6F, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x78 };
Span<byte> header = stackalloc byte[8];

FileInfo file = new FileInfo(path);
long length = file.Length;

using (BinaryReader br = new BinaryReader(file.OpenRead()))
{
br.BaseStream.Position = length - 0x200; //Where the "conectix" is located at
br.Read(header);
}

return vhdHeader.SequenceEqual(header);
}

分配较少的版本(如果您使用的是 .NET Core)。 (需要 C# 7.3)

编辑5:

private static bool IsVhd(string path)
{
Span<byte> vhdHeader = stackalloc byte[] { 0x63, 0x6F, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x78 };
Span<byte> header = stackalloc byte[8];

FileInfo file = new FileInfo(path);
long length = file.Length;

using (BinaryReader br = new BinaryReader(file.OpenRead()))
{
br.BaseStream.Position = length - 0x200; //Where the "conectix" is located at
for (int i = 0; i < 8; i++)
header[i] = br.ReadByte();
}

return vhdHeader.SequenceEqual(header);
}

相同,但适用于 .NET Framework(由于优化,最好是版本 4.7.1;还需要 System.Memory NuGet 包。C# 7.3)

编辑6: According to the specs ,似乎“硬盘页脚”位于最后 512(如果是在 MS Virtual PC 2004 之前创建的,则为 511)字节。

Note: Versions previous to Microsoft Virtual PC 2004 create disk images that have a 511-byte disk footer. So the hard disk footer can exist in the last 511 or 512 bytes of the file that holds the hard disk image.

Hard Disk Footer Field Descriptions
The following provides detailed definitions of the hard disk footer fields.
Cookie
Cookies are used to uniquely identify the original creator of the hard disk image. The values are case-sensitive.
Microsoft uses the “conectix” string to identify this file as a hard disk image created by Microsoft Virtual Server, Virtual PC, and predecessor products. The cookie is stored as an eight-character ASCII string with the “c” in the first byte, the “o” in the second byte, and so on.

如果文件大小小于 512 字节,我之前编写的代码将无法工作。我修复了它,现在它也可以处理带有 511 字节页脚的文件。此外,我添加了一些注释来帮助维护。

/// <summary>
/// Determines whether the file indicated by the given path is a valid Virtual Hard Disk (.vhd) file.
/// </summary>
/// <param name="path">The path to the .vhd file to check.</param>
/// <returns>Whether the file is a valid vhd file or not.</returns>
//https://www.microsoft.com/en-us/download/details.aspx?id=23850
//See 'Hard Disk Footer Format'
//ASCII string "conectix" (63 6F 6E 65 63 74 69 78) is stored at the last 512 (511 if created on legacy platforms) bytes of the file
private static bool IsVhd(string path)
{
if (path is null) throw new ArgumentNullException(nameof(path));

Span<byte> vhdFooterCookie = stackalloc byte[] { 0x63, 0x6F, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x78 };
Span<byte> cookie = stackalloc byte[9];

FileInfo file = new FileInfo(path);
long length = file.Length;
if (length < 511) return false; //Cannot be smaller than 512 bytes

using (BinaryReader br = new BinaryReader(file.OpenRead()))
{
br.BaseStream.Position = length - 0x200; //Where the footer starts from
#if NETCOREAPP
br.Read(cookie);
#else
for (int i = 0; i < 9; i++)
cookie[i] = br.ReadByte();
#endif
}

//SequenceEqual returns false if length is not equal, therefore we slice it to match
return vhdFooterCookie.SequenceEqual(cookie.Slice(0, 8))
|| vhdFooterCookie.SequenceEqual(cookie.Slice(1)); //If created on legacy platform
}

有一些条件编译位,但我相信你可以删除不必要的位来满足你的需要。

关于c# - 验证 .vhd 文件实际上是 vhd,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54295240/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com