[注:题目所说的“正确性” 其实并不准确,它指的是并非文件中的观点是否和谐,而是从二进制角度来看,一个文件和它(传输后)的副本内容经过逐个字节比较之后是否一致,英文为 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 出品的 fsum 和 HashCalc ,它们均可以计算多种不同格式的验证码)
实际验证
文件传输完毕后,现在开始比较本地磁盘文件和远程服务器上的文件:
ftp 客端软件上发送 XCRC 命令,等到服务器回送计算好的 crc32 验证码:
![]()
本地磁盘文件用 CheckCRC 计算 crc32 验证码:

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

Post a Comment