zoukankan      html  css  js  c++  java
  • MD5校验

    好久没有写随笔了,正好这两天可以休整一下,借此机会总结下最近使用python的小体会。

        个人体会文件校验在下载文件时使用较多,在linux下最简单的实现方式就是:

    1 $ md5sum filename
    2 21c7ee192e64569ce43cfb869bdb2755  filename

         当然在python当中也有对应的模块可以实现此功能,在python2.5之前可以使用 md5 模块,但是在python2.5以后就推荐使用 hashlib 来代替 md5 模块了。最简单的实现代码如下:

    #!/usr/bin/env python
    #coding : utf-8
    
    import sys
    import hashlib
    
    def md5sum(filename):
        file_object = open(filename, 'rb')
        file_content = file_object.read()
        file_object.close()
        file_md5 = hashlib.md5(file_content)
        return file_md5
    
    if __name__ == "__main__":
        file_md5 = md5sum(sys.argv[1])
        print file_md5.hexdigest()

        一个是传入 hashlib.md5() 的应该是 file_object.read() ,这样才是对文件内容产生md5校验码,竹风刚开始就是没有使用 read() 方法,而是传入filename(这样的md5是对文件名生成的),导致产生的校验码不对;
        另外一个地方是,调用了 hashlib.md5() 后返回的是一个对象,想要获得 linux 下 md5sum 同样的效果,还要调用一下 hexdigest() 方法。

        当然,上面的代码考虑得不够周全。如果要对一个比较大的文件进行校验,将会把文件内容一次读入内存,造成性能上的缺陷。个人比较推荐从http://ryan-liu.iteye.com/blog/1530029提供的代码,代码如下:

    #!/usr/bin/env python
    #coding : utf-8
    import hashlib, os
    
    def md5hex(word):
        """ MD5加密算法,返回32位小写16进制符号
        """
        if isinstance(word, unicode):
            word = word.encode("utf-8")
        elif not isinstance(word, str):
            word = str(word)
        m = hashlib.md5()
        m.update(word)
        return m.hexdigest()
    
    def md5sum(fname):
        """ 计算文件的MD5值
        """
        def read_chunks(fh):
            fh.seek(0)
            chunk = fh.read(8096)
            while chunk:
                yield chunk
                chunk = fh.read(8096)
            else: #最后要将游标放回文件开头
                fh.seek(0)
        m = hashlib.md5()
        if isinstance(fname, basestring) 
                and os.path.exists(fname):
            with open(fname, "rb") as fh:
                for chunk in read_chunks(fh):
                    m.update(chunk)
        #上传的文件缓存 或 已打开的文件流
        elif fname.__class__.__name__ in ["StringIO", "StringO"] 
                or isinstance(fname, file):
            for chunk in read_chunks(fname):
                m.update(chunk)
        else:
            return ""
        return m.hexdigest()

    还可以用:

        # 大文件的MD5值
        def getFileMd5(self, filename):
            if not os.path.isfile(filename):
                return
            myhash = hashlib.md5()
            f = file(filename, 'rb')
            while True:
                b = f.read(8096)
                if not b:
                    break
                myhash.update(b)
            f.close()
            return myhash.hexdigest()

    PS:至于为什么是8k?这个就涉及到了IO大小方面的内容了。提供一篇文章,有兴趣的可以看看了解下:http://blog.sina.com.cn/s/blog_6200c1440100vt4z.html

    转载:http://www.cnblogs.com/PandaBamboo/archive/2013/05/10/3071233.html

  • 相关阅读:
    NoSuchElementException if input is exhausted 报错
    批量更改文件后缀名
    初识Java
    简单cmd
    电脑操作简易快捷键
    java学习 Markdown+开始写博客
    JavaScript基础知识
    当数位数不够这,前面补0
    vs code 设置
    json日期格式转换为 2019-11-27 格式
  • 原文地址:https://www.cnblogs.com/zhjsll/p/5897443.html
Copyright © 2011-2022 走看看