将CryptoJS'的CryptoMD5状态保存为字符串并稍后恢复

Saving CryptoJS's CryptoMD5 state as a string and restoring it later

本文关键字:字符串 字符 串并 恢复 保存 状态 CryptoJS CryptoMD5      更新时间:2023-09-26

我逐渐计算一个大文件的MD5哈希值,在上传期间,然后在某些时候我想将我迄今为止计算的内容保存到HTML5 localStorage,以便以后能够恢复。

据我所知,localStorage可以存储字符串,所以我必须将渐进式MD5值存储为字符串,然后在用户稍后打开浏览器时恢复它们。

基本上我的代码是这样的:

var md5_full = CryptoJS.algo.MD5.create();
var wordArray = CryptoJS.lib.WordArray.create(chunk);
md5_full.update(wordArray);

此时,我想将md5_full转换为字符串,以便能够保存到localStorage。然后,在稍后的时间,当用户想要恢复上传时,能够从localStorage中检索md5_full,取消字符串化,并继续使用块更新它。

最后,我应该能够调用md5_full.finalize();来获得最终的完整MD5哈希摘要。

我认为问题可能与函数序列化有关- CryoJS显然试图序列化函数,但它可能无法正确恢复引用(作用域丢失)。

下面的代码通过只恢复数据而不恢复函数来避免这个问题。JSFiddle .

(反)序列化功能:

/** Serialize MD5 object. */
function stringify_md5(md5) {
    return JSON.stringify(md5);
}
/** Deserialize MD5 object. */
function parse_md5(serialized_md5) {
    var md5 = CryptoJS.algo.MD5.create();
    restore_data(JSON.parse(serialized_md5), md5);
    return md5;    
}
/** Recursively copy properties from object source to object target. */
function restore_data(source, target) {
    for (var prop in source) {
        var value = source[prop];
        if (typeof value == "object") {
            if (typeof target[prop] != "object") {
                target[prop] = {};
            }
            restore_data(source[prop], target[prop]);
        } else {
            target[prop] = source[prop];
        }
    }
}

用法示例:

var chunk1 = "abc", chunk2 = "def";
// The correct hash:
var md5_full_1 = CryptoJS.algo.MD5.create();
md5_full_1.update(chunk1);
md5_full_1.update(chunk2);
var correct_hash = md5_full_1.finalize();
// Using stringify/parse
var md5_full_2 = CryptoJS.algo.MD5.create();
md5_full_2.update(chunk1);
var md5_serialized = stringify_md5(md5_full_2); // serialize
md5_full_2 = parse_md5(md5_serialized);  // deserialize
md5_full_2.update(chunk2);
var result_hash = md5_full_2.finalize();
alert(correct_hash.toString() == result_hash.toString()); // true

(使用WordArray使我在CryptoJS中出现错误,因为某些原因)