2011-05-03 59 views
1

我有一个应用程序从服务器下载文件。连接非常不稳定,所以我们正在实现一个功能来检查文件的完整性,以便我们知道文件是否没有正确下载并进行相应的管理。如何进行散列传输以进行文件完整性检查?

我应该如何去做这个过程?现在我向服务器请求文件的散列,然后我再次请求文件本身,然后计算下载文件和文件的散列,并比较这两个散列。

这是正确的做法吗?有些事告诉我,事实并非如此。如果发现哈希值不同,我会经历几次完全相同的过程,包括再次请求哈希值(应该是相同的)。我应该每次都需要散列吗?如果传输不正确,我会这样做吗?这是不必要的?有没有办法让我减少请求的数量,因为它们很贵,而且现在的情况很慢。

任何想法?

以防万一它的问题服务器使用C#和客户端是一个Android设备(JAVA)。

谢谢,

+1

哈希匹配是*证据*文件正确传输,但不是*保证*;哈希碰撞。你正在玩的几率。因此,您的策略应该是计算各种策略的预期价值和预期成本,然后为客户选择预期净值最高的那一种。 – 2011-05-03 14:48:48

+0

也就是说,我的策略是保持简单。如果传输失败,或者它“成功”,但哈希不匹配,则不要再尝试。告诉用户该尝试失败,并让他们决定是再试一次还是放弃。如果连接速度很慢,那么最终它就是你花费的用户*时间;让他们决定如何使用它。 – 2011-05-03 14:49:46

回答

3

TCP/IP自己做完整性检查;你不需要。每个数据包的完整性通过CRC来确保,TCP协议检查丢失的数据包并请求重新提交。因此,只要您的服务器生成Content-Length标头,您就可以确定检测到传输错误,并且客户端出错。

也就是说,一个文件哈希的好地方是一个自定义的HTTP头。在“X-”前加上其名称,以免它与现有或未来的标准标题相冲突。

+0

实际上,只有在TCP连接要用于传输多个文件时,才需要HTTP内容长度标头(或任何其他传输内容长度的方式)。如果只有一个文件通过TCP套接字传输,则接收端能够判断发送方是否正确地关闭了连接(在发送最后的数据之后)或者连接断开,例如,由于网络问题。 – jarnbjo 2011-05-03 15:02:51

+1

数据不一定必须在传输中被破坏:https://forums.aws.amazon.com/thread.jspa?threadID=22709 – 2011-05-03 15:11:15

2

是的,还有更好的办法。首先,不是要求整个文件的散列,而是压缩文件并将压缩数据分割成(比方说)100KB块,并提供一个散列序列,每块一个,然后是这些散列序列的自散列。通过自我散列,我只是指采用散列向量,散列并将其附加在向量的末尾。

您现在可以通过检查自散列来验证散列的这个向量是否正确传输。如果不通过,请重新请求哈希向量。

然后第二阶段请求传输压缩数据。遇到这种情况,您可以每隔100KB检查一次传输是否正确,一旦出现错误就立即中止。然后(如果可能的话)从您离开的地方开始重新请求,即“高潮标记”。

最后,您可以安全地解压缩数据。许多解压缩算法将执行进一步的完整性检查,从而为您提供进一步的验证 - 防止出现任何编程错误。免费支票是值得的。

无论您是否正在使用TCP/IP检查协议或UDP等不可靠协议,此方法都可行。压缩数据,如果你不这样做,也将是一个重大的改进。

唯一的缺点 - 这显然是更多的工作。