SHA1 计算 returns 错误值

SHA1 calculation returns wrong value

我正在尝试使用 javascript 计算文件的 SHA1 值。 该文件位于与 index.html 相同的目录中,并使用 ajax 通过作为查询参数给出的名称加载。

例如,调用 http://localhost:7070/index.html?file=file.zip 应该为 file.zip

计算 SHA1

以下代码计算 SHA1 但结果与我使用带有 SHA1 的在线工具并上传文件得到的结果不同 http://onlinemd5.com/

$(document).ready(function(){
   var file = utils.getUrlVars() && utils.getUrlVars().file;

   if (!file) throw "error - no URL was found. set 'file' in query string.";

   $.ajax({

       url: file,
       success: function(data){
           var sha1= CryptoJS.SHA1(data).toString();
           console.log('sha1 - success', sha1);
       },
       error: function(error){
           console.log('ERROR');
       }

   })
});

有什么区别?我想在线工具计算正确(并且它还给我使用 Java 代码计算时得到的确切结果),所以此 JS 代码中的某些内容略有不同。

问题肯定不在 CryptoJS 包中,因为在使用脚本计算字符串 'hello' 时会生成以下输出:

sha1 - success aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d

使用在线工具,你会得到相同的结果(大写):

AAF4C61DDCC5E8A2DABEDE0F3B482CD9AEA9434D

肯定是数据加载后的格式或使用方式的问题

当我使用 Java 计算 SHA1 时,我通过在文件字节数组上计算它得到了相同的结果,所以它表明我使用这个脚本得到的字节数组在某种程度上是不同的/部分的。

根据the manual for .ajax,您需要将dataType选项设置为text,否则它会尝试猜测类型,然后text永远不是一个选项。

我们最终设法解决了这个问题,解决方案是纯 JS,没有 Ajax 涉及:

$(document).ready(function(){

var url = utils.getUrlVars() && utils.getUrlVars().url;

if (!url) throw "error - no URL was found. set 'url' in query string.";

var oReq = new XMLHttpRequest();
oReq.open("GET", url, true);
oReq.responseType = "blob";

oReq.onreadystatechange = function(e) {

    if (oReq.readyState == 4 && oReq.status == 200) {
        console.log('xhr success');
        success(e);
    } else if (oReq.readyState == 4 && oReq.status != 200){
        console.log('xhr error');
        error(e);
    }
}

var success = function() {
    var blob = oReq.response; 
    var sha1 = CryptoJS.algo.SHA1.create(); 
    var reader = new FileReader();
    reader.readAsArrayBuffer(blob);

    reader.onload = function(e) {
        var arrbuffer = e.target.result.slice(0, e.target.result.byteLength);
        var bytes = CryptoJS.enc.u8array.parse(new Uint8Array(arrbuffer));
        sha1.update(bytes);
        var sha1res = sha1.finalize().toString(CryptoJS.enc.Hex);
        // print results
        console.log('sha1 - success', sha1res);
    }
};

var error = function(){
    IJavaScriptImplementer.onError(JSON.stringify(error));
    IJavaScriptImplementer.log(JSON.stringify(error));
}

oReq.send(null);
});

如您所见,文件以 blob 形式请求,并作为一个切片读取(您也可以逐片读取,但在我的情况下文件很小),然后读取并计算字节进入 SHA1 值。