python 在比较 2 个文件一致性时是否该使用 MD5 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
caduke
V2EX    Python

python 在比较 2 个文件一致性时是否该使用 MD5

  •  
  •   caduke 2016-02-19 10:01:43 +08:00 7958 次点击
    这是一个创建于 3523 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,由于 md5 校验也需要读取文件,所以使用 open 的'br'模式读取部分内容会不会更直接呢?
    如果 md5 更好,好在什么地方呢?

    22 条回复    2016-02-22 03:55:18 +08:00
    zzn
        1
    zzn  
       2016-02-19 10:33:18 +08:00
    如果有两个文件,应该是直接读取会直接一点,但哪种更快?要实际比较一下
    Septembers
        2
    Septembers  
       2016-02-19 10:35:13 +08:00 via Android
    要验证完整性的话 建议使用 Hash 算法
    jimzhong
        3
    jimzhong  
       2016-02-19 10:37:12 +08:00
    如果只要比较两个文件,且都在本地,则直接比较更好。
    rock_cloud
        4
    rock_cloud  
       2016-02-19 10:40:29 +08:00
    如果两个文件的 MD5 不相同,则文件内容一定不相同,如果两个文件的 MD5 相同,则文件内容可能相同。
    所以如果是比较一个文件和许多其他文件是否相同,并且提前知道其他文件的 MD5 值,则先比较 MD5 值可以大大提高文件比较的速度。
    lhbc
        5
    lhbc  
       2016-02-19 10:45:42 +08:00 via Android
    要确保 100%正确就必须校验全文
    而且不能使用 MD5 这种极易碰撞的算法,起码 SHA1 ,最好 SHA256
    congeec
        6
    congeec  
       2016-02-19 10:49:38 +08:00 via iPad
    文件大小,文件多不多,要比较几次都影响算法
    Frapples
        7
    Frapples  
       2016-02-19 11:07:26 +08:00   2
    比较两个文件一致性有两种方案:
    1. 直接逐字节比较文件内容
    2. 使用 md5 等 hash 算法比较


    论程序执行效率来说,方案 1 需要把两个文件的内容都扫一遍, hash 算法肯定比单单扫一遍文件内容要慢。不过考虑到 python 中 hash 算法是优化过的 C 实现的,扫文件内容则是单纯的 python 代码, hash 应该没想象的慢。。。
    然而值得注意的是,假如这两个文件是跨主机的呢?需要用网络传递信息呢?这种情况下,考虑到网络传输慢很多,方案一需要传递长长的文件内容,但是方案二只需要传递短短的 hash 就 ok 了。

    论程序可靠性来说, hash 算法有碰撞的可能,尤其是 md5 这种已经过时的 hash 算法,人为碰撞的可能性更大。但是直接比文件内容就没这个问题了, 100%靠谱。

    从程序容易写这方面看,无论方案一还是二几句代码就能搞定吧 。。。

    所以的话,本地程序还是逐字节比较好,但是跨主机的用 hash 较好。要注意的是不要用 md5 这种过时 hash ,应该采用类似 sha512 这种霸气点的。
    caduke
        8
    caduke  
    OP
       2016-02-19 11:14:11 +08:00
    感谢大家的回答,原本只是想到如果多加一层 hash 校验性能会更差,但是了解了 hash 是 C 实现的,所以不那么认为了!
    aec4d
        9
    aec4d  
       2016-02-19 11:23:19 +08:00
    怕个毛碰撞-_- MD5+CRC32
    otakustay
        10
    otakustay  
       2016-02-19 11:23:48 +08:00
    如果这 2 个文件没有事先就存在的 MD5 码,那么你生成 MD5 也是需要全部读取一的,不如就地读取判等,省了 MD5 的 CPU 开销
    如果原来就有 MD5 码,且文本本身是存在意义的(如小说等可读文字、论坛用户提交的贴子,不是一堆随便构造的乱码),那么 MD5 可以认为是可信的,在有意义的前提下构造 MD5 冲撞概率太小
    如果这类比较会在今后频繁发生,那么使用 MD5 并存下来是个不错的选择
    wbsdty331
        11
    wbsdty331  
       2016-02-19 11:24:09 +08:00
    md5 有可能碰撞
    试试 crc32 或者 sha1
    fy
        12
    fy  
       2016-02-19 11:46:06 +08:00
    为什么总想着碰撞所以要全文比较呢?

    1. 如果两个文件都是本地文件,全文比较也无不可
    2. 如果其中一个是网络文件:提取文件的大小、前 XXX 字节、哈希作为特征值,碰撞概率基本可以忽略不记了。
    wy315700
        13
    wy315700  
       2016-02-19 11:46:25 +08:00
    hmac
    Anteiku
        14
    Anteiku  
       2016-02-19 12:09:59 +08:00 via Android
    billlee
        15
    billlee  
       2016-02-19 13:28:05 +08:00
    @wbsdty331 crc32 更可能碰撞
    otakustay
        16
    otakustay  
       2016-02-19 13:43:23 +08:00
    @wbsdty331 没有不会碰撞的摘要算法,不过 md5 有相对成熟的创造碰撞的方法就是了
    realpg
        17
    realpg  
    PRO
       2016-02-19 14:09:28 +08:00
    计算任何 hash 时候,都要把文件内容完整读一遍,而且运算过程本身也是执行开销。总内存消耗量应该是把两个文件分别执行 md5 的过程总内存开销中的大者。
    直接读取进来比较的话,总内存消耗量就是俩文件大小之和,近似的。
    本地文件,不是巨大文件,语言有比较方便的大文件数据读入比较,倾向于直接比较。

    如果 hash 比较,建议使用 md5+crc 之类双轻计算 hash ,能同时碰撞两个 hash 的冲突,很难构造,对于一般安全级别足够了
    raptor
        18
    raptor  
       2016-02-19 14:37:53 +08:00
    MD5 都碰撞了,还 CRC32 …… CRC32 的碰撞率比 MD5 高得多得多得多……而且构造一个 CRC32 碰撞也比构造一个 MD5 碰撞容易得多得多得多……
    VYSE
        19
    VYSE  
       2016-02-19 16:36:37 +08:00
    HASH 比较仅仅好在多个文件比较
    两个文件比较,请用 filecmp.cmp
    WhoMercy
        20
    WhoMercy  
       2016-02-19 16:49:43 +08:00
    如果文件大小不确定,直接比较文件的内容是效率极低的方法。

    我认为正确的姿势应该是:
    1.保存(或生成)文件时,既对文件进行 hash 值生成(空闲时生成以备后用,避免使用时耗费时间)
    2.先比较文件的外部属性,如 size 等
    3.比较 hash 值
    (其实到这里就应该结束了)
    4.如果还不放心,可以继续比较两文件特定大小、特定位置的 stream (等同于二次比较 hash 值,碰撞几率减半)(是否比较根据你需要的精确度来确定)
    akira
        21
    akira  
       2016-02-19 17:47:46 +08:00
    如果只是对特定的 2 个文件做比较,那随便你怎么弄都行。
    如果是对一大堆文件做比对,那肯定还是先用哈希算法做一次过滤比较好。
    SlipStupig
        22
    SlipStupig  
       2016-02-22 03:55:18 +08:00
    @lhbc md5 极易碰撞,大神很多网络证书的 sign 都是 md5 ,还有很多网站后台认证算法都是裸奔的 MD5 ,劫持入侵数据指日可待啊!
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2851 人在线   最高记录 6679 nbsp;     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 00:29 PVG 08:29 LAX 17:29 JFK 20:29
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86