我想为未记录的RtlCrc32和RtlCrc64函数请求一个有效的P / Invoke定义。
我知道托管代码中现有的CRC-32算法,但我更倾向于采用Microsoft Windows的方式来避免可能的人为错误和/或由于缺乏校验和计算经验而产生的负面表现。
这些是在winnt.h头文件(Windows 10 SDK)中声明的函数:
//
// Crc32 and Crc64 routines that use standardized algorithms
//
NTSYSAPI
DWORD
NTAPI
RtlCrc32(
_In_reads_bytes_(Size) const void *Buffer,
_In_ size_t Size,
_In_ DWORD InitialCrc
);
NTSYSAPI
ULONGLONG
NTAPI
RtlCrc64(
_In_reads_bytes_(Size) const void *Buffer,
_In_ size_t Size,
_In_ ULONGLONG InitialCrc
);
这就是我试过的:
[DllImport("NtDll.dll", SetLastError=false)]
public extern static uint RtlCrc32([In] IntPtr buffer,
[In] IntPtr size,
[In] uint initialCrc);
[DllImport("NtDll.dll", SetLastError=false)]
public extern static ulong RtlCrc64([In] IntPtr buffer,
[In] IntPtr size,
[In] ulong initialCrc);
和:
byte[] bytes = File.ReadAllBytes(@"C:\File.txt");
uint initialCrc = 0; // I tried to use 0x4C11DB7
// standarized polynomial value
// just to try something random.
IntPtr buffer = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes, 0, buffer, bytes.Length);
uint crc32 = NativeMethods.RtlCrc32(buffer, new IntPtr(bytes.Length), initialCrc);
Console.WriteLine(crc32.ToString("X2"));
但是当我将返回值与计算CRC-32的任何其他程序进行比较时,我的值不对应。
因为我对C / C ++没有经验,所以我有些疑惑......首先我不知道函数是否返回NTSATUS错误代码,或者它们分别返回DWORD和ULONGLONG。其次,我没有得到我需要传递给InitialCrc
参数。
你的定义很好。这些函数返回CRC值而不是错误代码。
将缓冲区声明为byte[]
可能更容易,并让编组器为您固定数组,避免复制。
初始值是CRC算法输入的一部分。当与另一个CRC算法的输出进行比较时,您需要知道使用了什么初始值。