如何在二进制数据上计算MD5
JS - How to compute MD5 on binary data
EDIT:从更改标题"JS文件API -读写UTF-8数据不一致"以反映实际问题。
我有一些二进制内容,我需要计算MD5。内容是一个WARC文件,这意味着它包含文本和编码图像。为了避免文件保存中的错误,我将所有数据转换并存储在arrayBuffers中。所有数据放入UInt8Array
s中转换为UTF-8。
我的第一次尝试,测试,是使用saveAs
库从Chrome扩展保存文件。这意味着我使用了一个blob对象来传递给方法并创建文件。
var b = new Blob(arrayBuffers, {type: "text/plain;charset=utf-8"});
saveAs(b,'name.warc');
我没有找到一个工具来从Blob
对象计算MD5,所以我正在做的是使用FileReader
读取blob文件作为二进制数据,然后使用MD5工具(我使用cryptoJS以及faultylabs的工具)来计算结果。
f = new FileReader();
f.readAsBinaryString(b);
f.onloadend = function(a){
console.log( 'Original file checksum: ', faultylabs.MD5(this.result) );
}
资源(图像)是直接以arraybuffer
格式下载的,所以我不需要转换它们。
结果是错误的,这意味着从代码中检查MD5并从我保存在本地机器上的文件中检查MD5会得到2个不同的结果。作为文本阅读,显然会出现错误。
我发现的解决方案包括使用文件系统API在磁盘上写入blob对象,然后将其作为二进制数据读取,计算MD5,然后将检索到的文件保存为WARC文件(不是直接的blob对象,而是这个"刷新"版本的文件)。在这种情况下,计算的MD5是好的(我在warc文件的"刷新"版本上计算它),但是当我用"刷新"warc存档启动warc重播实例时,它会抛出错误-而原始文件我没有任何问题(但MD5不正确)。
var fd = new FormData();
// To compute the md5 hash and to have it correct on the server side, we need to write the file to the system, read it back and then calculate the md5 value.
// We need to send this version of the warc file to the server as well.
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
function computeWARC_MD5(callback,formData) {
window.requestFileSystem(window.TEMPORARY, b.size, onInitFs);
function onInitFs(fs) {
fs.root.getFile('warc.warc', {create: true}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function(e) {
readAndMD5();
};
fileWriter.onerror = function(e) {
console.error('Write failed: ' + e.toString());
};
fileWriter.write(b);
});
});
function readAndMD5() {
fs.root.getFile('warc.warc', {}, function(fileEntry) {
fileEntry.file( function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
var warcMD5 = faultylabs.MD5( this.result );
console.log(warcMD5);
var g = new Blob([this.result],{type: "text/plain;charset=utf-8"});
saveAs(g, o_request.file);
formData.append('warc_file', g)
formData.append('warc_checksum_md5', warcMD5.toLowerCase());
callback(formData);
};
reader.readAsBinaryString(file);
});
});
}
}
}
function uploadData(formData) {
// upload
$.ajax({
type: 'POST',
url: server_URL_upload,
data: fd,
processData: false,
contentType: false,
// [SPECS] fire a progress event named progress at the XMLHttpRequestUpload object about every 50ms or for every byte transmitted, whichever is least frequent
xhrFields: {
onprogress: function (e) {
if (e.lengthComputable) {
console.log(e.loaded / e.total * 100 + '%');
}
}
}
}).done(function(data) {
console.log('done uploading!');
//displayMessage(port_to_page, 'Upload finished!', 'normal')
//port_to_page.postMessage( { method:"doneUpload" } );
});
}
computeWARC_MD5(uploadData, fd);
saveAs(b, 'warc.warc');
谁能解释一下为什么有这种差异?在处理所有我正在处理的对象作为二进制数据(存储,读取)我错过了什么?
基本上,我尝试了另一种方法,并将blob文件转换回arraybuffer并在其上计算MD5。此时,文件的MD5和arraybuffer的MD5是相同的。
var b = new Blob(arrayBuffers, {type: "text/plain;charset=utf-8"});
var blobHtml = new Blob( [str2ab(o_request.main_page_html)], {type: "text/plain;charset=utf-8"} );
f = new FileReader();
f.readAsArrayBuffer(b);
f.onloadend = function(a){
var warcMD5 = faultylabs.MD5(this.result);
var fd = new FormData();
fd.append('warc_file', b)
fd.append('warc_checksum_md5', warcMD5.toLowerCase());
uploadData(fd);
}
我猜从二进制字符串和从缓冲区数组的结果是不同的,这就是为什么MD5也不一致。
- 根据元素和容器大小计算边距
- 从Rally获取一个特定的标记,以便计算另一个字段中的值
- 使用D3.js计算带有字母间距的文本长度
- 使用CSS或JavaScript计算分页符的数量
- 可以't计算自定义谷歌地图的js
- 如何计算每个元素's的高度,并将这些值用作函数中的变量
- JavaScript计算帮助(乘以时间)
- 如何计算对象文字中的键
- JavaScript循环无法正确计算/显示结果
- 与域在同一台计算机上运行的NODEJS服务器的CORS错误
- 四舍五入JavaScript计算
- 计算HTML中的页数
- 使用jQuery计算数组中的对象以更改进度条
- 如何在jquery中使用实时计算求和值
- 计算多个项目的价格
- 如何在 Postman 中的预请求脚本中计算 md5 哈希
- javascript中MD5计算的预期性能
- JavaScript 中的 HTTP 摘要.新 URI 的 MD5 重新计算
- 如何使用CryptoJS计算blob的md5校验和
- 如何在二进制数据上计算MD5