简单实现JavaScript计算文件MD5值

2018-01-24 0 条评论 745 次阅读 4 人点赞

说明:

md5是一个将任意长度的数据字符串转化成短的固定长度的值的单向操作。任意两个字符串不应有相同的散列值(即,有“很大可能”是不一样的,并且要人为地创造出来两个散列值相同的字符串应该是困难的)。 因此md5经常用于校验字符串或者文件,因为如果文件的md5不一样,说明文件内容也是不一样的,即经过修改的,如果发现下载的文件和给的md5值不一样,就需要慎重使用。
md5文件校验用途非常多,例如:游戏patch包的校验,病毒文件确认,app提审校验等等,只要需要确认某一个文件的唯一性和正确性,都会使用md5作为校验。因此我们也经常会使用用到计算文件md5的工具,在一般的后端语言中,都可以进行计算,但是会比较麻烦。
所以今天带来的是使用JS计算文件的md5,不会上传文件到后台,而只是在前端进行计算,非常方便,且不涉及隐私问题。

具体实现

这里使用到了Github上的一个名叫SparkMD5 的开源项目,配合原生js即可实现计算文件md5。

首先下载SparkMD5 https://github.com/satazor/js-spark-md5/releases,并且在html页面中引入它:

<!-- 引入SparkMD5 -->
<script src="js/spark-md5.min.js" ></script>

 

其次,html部分需要一个上传的input,配合上简单的bootstrap,效果如下:

主要代码如下:

<!-- 上传文件的input -->
<div class="control-group">

    <div id="file" style="text-align:center">
        <label for="filemd5" class="btn btn-large btn-info btn-block" data-toggle="tooltip" title="本工具使用html5的api计算文件的md5,不会上传文件到后台,请放心使用。">
            <h2>&nbsp;&nbsp;&nbsp;
                <i class="icon-upload"></i>&nbsp;&nbsp;上&nbsp;传&nbsp;文&nbsp;件&nbsp;&nbsp;&nbsp;</h2>
        </label>
        <input id="filemd5" name="filemd5" type="file" style="display:none">
        <label class="control-label" style="margin-top:5px;">上传时间取决于文件大小,请耐心等待结果显示</label>
    </div>
</div>
<hr>
<!-- /control-group -->



<!-- 显示计算结果的div -->
<div class="control-group" style="text-align:center">
    <!-- <label class="control-label" ><h3>文件MD5值</h3></label> -->
    <div class="controls ">
        <h3 id="md5box" data-toggle="tooltip" data-placement="bottom" title="此处的32位字符串即为文件的MD5 hash,对比此hash值就可以知道文件是否被修改,详情请看下方说明。"></h3>
    </div>
    <!-- /controls -->
</div>
<!-- /control-group -->

接下来,我们使用js里的addEventListener去监听这个文本框的变化,一旦有上传任务,就开始处理。同时我们注意到,文件可能会很大,不可能直接一整块去进行计算,因此这里把文件按照每个2M的方式去切割,切割完成后统一处理,具体代码如下:

//监听文本框变化
document.getElementById("filemd5").addEventListener("change", function () {
    //声明必要的变量
    var fileReader = new FileReader(), md5box = document.getElementById('md5box');
    //文件分割方法(注意兼容性)
    blobSlice = File.prototype.mozSlice || File.prototype.webkitSlice || File.prototype.slice,
        file = document.getElementById("filemd5").files[0],
        
        //文件每块分割2M,计算分割详情
        chunkSize = 2097152,
        chunks = Math.ceil(file.size / chunkSize),
        currentChunk = 0,

        //创建md5对象(基于SparkMD5)
        spark = new SparkMD5();  
    var filename = document.getElementById("filemd5").files[0].name;
    var filesize = document.getElementById("filemd5").files[0].size/1024;
    filesize = filesize.toFixed(2);
        //每块文件读取完毕之后的处理
    fileReader.onload = function (e) {
        // console.log("读取文件", currentChunk + 1, "/", chunks);
        //每块交由sparkMD5进行计算
        spark.appendBinary(e.target.result);
        currentChunk++;

        //如果文件处理完成计算MD5,如果还有分片继续处理
        if (currentChunk < chunks) {
            loadNext();
        } else {
            // 前台显示Hash
            md5box.innerHTML = '文件:' + filename +'('+filesize+'KB)<div class="alert alert-success">MD5 Hash<h3 style="color:red;">' + spark.end()+"</h3></div>";
        }
    };

    //处理单片文件的上传
    function loadNext() {
        var start = currentChunk * chunkSize, end = start + chunkSize >= file.size ? file.size : start + chunkSize;

        fileReader.readAsBinaryString(blobSlice.call(file, start, end));
    }

    loadNext();
});

最终实现的效果如下:

Gif演示:

当然这只是这个开源库的简单应用,更多的应用,感兴趣的小伙伴可以去github上查看相关文档和说明,地址是:https://github.com/satazor/js-spark-md5

 

Kiwi

Valar Morghulis

文章评论(0)