Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从ReadFile中检测错误数据_C_Windows_Readfile - Fatal编程技术网

C 从ReadFile中检测错误数据

C 从ReadFile中检测错误数据,c,windows,readfile,C,Windows,Readfile,我有一个函数,它应该读取一个.dat文件,其中包含一个结构数组,定义如下: struct data{ char name[30]; double age; } struct data buffer[80]; 文件中不允许有其他数据 我想保护用户不读取不包含上述结构的文件。如果我尝试读取一些随机的.docx文件或其他文件,那么出错的可能性非常高 如何确保用户不能读取他或她不应该读取的文件?是否有办法确定文件中的数据是结构还是其他 我正在使用ReadFile函数并将数据保存到缓冲区中 仅

我有一个函数,它应该读取一个.dat文件,其中包含一个结构数组,定义如下:

struct data{
  char name[30];
  double age;
}

struct data buffer[80];
文件中不允许有其他数据

我想保护用户不读取不包含上述结构的文件。如果我尝试读取一些随机的.docx文件或其他文件,那么出错的可能性非常高

如何确保用户不能读取他或她不应该读取的文件?是否有办法确定文件中的数据是结构还是其他

我正在使用ReadFile函数并将数据保存到缓冲区中


仅仅确保它是一个.dat文件是不够的,因为这样的文件可以包含任何内容

您可以像许多文件格式一样,在文件开头写一个特殊的签名(无论您选择什么)。例如,所有.ZIP文件都包含

50 4B 05 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
(即“PK”,后跟“0x05”、“0x06”和18个空字节)

您只需首先从文件中读取与文件签名大小相等的字节数,并将其与签名进行比较。如果它们匹配,则从签名长度后的第一个字节开始读取,直到文件末尾

如果文件始终包含80个数据结构,则可以通过读取文件大小,减去用于签名的字节数,然后将剩余部分除以80个数据结构的大小来添加额外的验证。如果签名和字节大小都匹配,则可能是您的文件


编辑后,表示无法修改数据文件的结构,第二个选项实际上是唯一可行的选项。只需删除与跳过签名大小字节相关的部分;读取以字节为单位的文件大小,并将其除以
sizeof(data)
,它应该等于80。这不是一个完美的解决方案,但如果不能修改布局以添加更具体的内容,这可能是您所能做的最好的解决方案。

阅读您的数据,然后检查是否

  • name
    是以零结尾的字符串,最少包含1个字符,最多包含29个字符。至少它不应包含小于空格的字符和字符代码
    0x7F
    0xFF
    。也许您可以进行更多测试——如果您将这些名称作为UTF-8输入,那么所有高于或等于
    0x80
    的代码都应该与UTF-8规范匹配

  • age
    应该是有效的
    double
    数字,并且在一定范围内。例如,年龄
    -0.005
    ,显然是无效的;
    4.7E14
    也是如此

  • 名称
    数组中终止零后未使用的字节设置为“已知”值或序列。读取时,测试是否返回了预期的字节

  • 这应该适用于小数据库中的所有项

    如果可以扩展现有结构,可以设计一个“神奇”校验和并附加它。然后,如果重新计算该校验和与存储的校验和不匹配,则表明有问题。校验和可以简单到将所有字节相加,只存储最低的字节,或将它们异或到一起,或使用Adler-32或CRC32,这取决于您希望它有多安全


    (在创建校验和之前,最好确保将
    名称
    数组中未使用的字节设置为已知的固定值。)

    因为这是用Windows标记的,所以我会将签名粘贴在。这样,您不需要修改所需的文件格式,但仍然可以灵活地存储随文件移动的强签名


    尽管这会限制您使用NTFS文件系统。

    问题是,它应该能够读取我正在执行的项目规范中给出的文件。那是行不通的。好吧,我做到了。不过,你还有最后一点要说。我可以检查文件大小是否是sizeof(data)的倍数。但这并不是充分的证据。在我花时间回答之前,你应该在你的问题中提出这个要求,而我并不知道这个事实。那么我的第二个建议是唯一的选择;只需省略减去签名大小的部分,并使用文件大小除以结构大小-它应该平均分割,没有余数。这当然不是万无一失的,但是你已经表明你不能做任何事情来做到这一点(现在)。在你的文件中签名。或者只是信任用户。