Skip to content

验证ftp传输后文件的正确性

[注:题目所说的“正确性” 其实并不准确,它指的是并非文件中的观点是否和谐,而是从二进制角度来看,一个文件和它(传输后)的副本内容经过逐个字节比较之后是否一致,英文为 integrity,中文似乎没有很准确的对译,“正确性”、“完整性”、“一致性”都只是它的一个方面。]

如何比较分别在本地和远程的两个文件是否一样呢? 常见的方法是双方分别从文件计算出一个很短的验证码(hash 值),然后比较这两个验证码是否一样,因为验证码本身很短小,传输它的过程和比较它和成本均远远低于对实际文件的操作。两端分别算出的验证码如果不同,足以证明文件不一致,而验证码相同并不能100%证明文件内容一定一致,但不同文件算出同样验证码的几率非常之小,在实际文件传输应用中几乎不会碰到。

计算验证码的办法有多种,包括相对简单的CRC32,常用的 md5sum,SHA等等。许多 P2P 软件也有它们自己的算法,如 eDonkey 协议中生成文件的标识符的算法。

用 ftp 服务器分享文件有用户方面操作简单的优点,但 ftp 协议比较陈旧,设计上也存在当初考虑不周的地方,比如如何验证本地文件和服务器上文件是正确/一致的问题,标准的 ftp 只能给出服务器上的文件大小,而根据文件大小是无法判断两个文件拷贝是否是一样的。

针对这个问题,许多 ftp 服务器增加了一些计算 hash 值的扩展功能,如XCRC/XMD5/XSHA,可以计算出服务器上文件的 CRC32/md5sum/SHA 验证码,用户可以计算出本地文件的验证码,和服务器报告的加以比较,如果两个验证码一致,基本上就可以确定两个文件是一模一样的。
如何检查 ftp 服务器提供验证码功能呢?连接服务器后,向服务器发送 FEAT 或者 HELP 命令获取服务器支持的功能列表,观察其中是否包括 XCRC/XMD5/XSHA 等验证命令。我的 XP机器上面运行 zFTPServer,这是在 Command Prompt 中输入 FEAT / HELP 命令后回送的列表:

C:\>ftp localhost
Connected to MyServer.
220 Welcome to zFTPServer
User (MyServer:(none)): userl
331 User name received, need password.
Password:
230 User logged in, proceed.
ftp> literal FEAT
211-Extensions supported:
AUTH TLS;AUTH TLS-C;SSL;TLS-P;
CCC
CLNT
UTF8
CPSV
EPRT
EPSV
LIST -laT
MDTM
MDTM YYYYMMDDHHMMSS filename
MFF Modify;
MFMT
MLSD
MLST size*;Type*;Modify*;
PBSZ
PROT
REST STREAM
SITE ZONE;UTIME
SIZE
SPSV
SSCN
STAT -laT
TVFS
XCRC “filename” start end
XMD5 “filename” start end

Compliance Level: 20020901 (IETF mlst-16)
211 End of extensions.
ftp> literal HELP
214-The following commands are recognized (* => unimplemented, + => extension).
214-    ABOR      DELE      MFMT      MSOM*     REST      STOU
214-    ACCT*     ENC*      MIC*      NLST      RETR      STRU
214-    ALLO      EPRT      MKD       NOOP      RMD       SYST
214-    APPE      EPSV      MLFL*     OPTS      RNFR      TYPE
214-    AUTH      FEAT      MLSD      PASS      RNTO      USER
214-    CCC       HELP      MLST      PASV      SITE      XCRC
214-    CDUP      LIST      MMD5      PBSZ      SIZE      XCUP
214-    CLNT      MAIL*     MODE      PORT      SMNT      XCWD
214-    COMB      MD5       MRCP*     PROT      SPSV      XMD5
214-    CONF*     MDTM      MRSQ*     PWD       SSCN      XMKD
214-    CPSV      MFCT      MSAM*     QUIT      STAT      XPWD
214-    CWD       MFF       MSND*     REIN      STOR      XRMD
214
ftp>

可见我的服务器支持两种验证方式: XCRC 和 XMD5。这两种方式均支持对文件全部或部分生成验证码(文件名后发送开始偏移量和结束偏移量即可计算文件中一部分的验证码)。为简单起见,下面只讨论对整个文件用 XCRC 验证的情况。

准备工作

首先,在ftp 客端软件方面,你需要知道怎样向服务器发送 XCRC 命令请求,很多 ftp 客端软件都允许用户发送 custom command,例如在 SmartFTP 中可以增加一条XCRC 的 custom command:

其次,你需要知道怎样计算本地硬盘上的文件的 CRC32 验证码,这里的例子使用 CheckCRC :

(我个人更喜欢 slavasoft 出品的 fsumHashCalc ,它们均可以计算多种不同格式的验证码)

实际验证

文件传输完毕后,现在开始比较本地磁盘文件和远程服务器上的文件:

ftp 客端软件上发送 XCRC 命令,等到服务器回送计算好的 crc32 验证码:

本地磁盘文件用 CheckCRC 计算 crc32 验证码:

两者的结果都是 4C19D738,通过验证。

顺便说一下,有些强大的 ftp 客户端软件会利用这个功能,在文件传输完毕和断点续传之前可自动验证文件,然后根据验证结果决定是否重新传输,比如 SmartFTP 就可以启动 CRC Check:

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*


为了防止恶意的垃圾评论脚本,请输入以下图片里面的数学方程式的答案。
防垃圾评论问题