How to deterministically verify that a JSON object hasn't been modified?

前端 未结 8 1703
忘了有多久
忘了有多久 2020-11-30 04:38

According to MDN documentation for JSON.stringify:

Properties of non-array objects are not guaranteed to be stringified in any particular order. Do

相关标签:
8条回答
  • 2020-11-30 05:22

    These days I've been playing with the deterministic way to stringify an object and I've written the ordered object stringify to JSON, that solves the above noted dilemma: http://stamat.wordpress.com/javascript-object-ordered-property-stringify/

    Also I was playing with custom hash table implementations which is also related to the topic: http://stamat.wordpress.com/javascript-quickly-find-very-large-objects-in-a-large-array/

    //SORT WITH STRINGIFICATION
    
    var orderedStringify = function(o, fn) {
        var props = [];
        var res = '{';
        for(var i in o) {
            props.push(i);
        }
        props = props.sort(fn);
    
        for(var i = 0; i < props.length; i++) {
            var val = o[props[i]];
            var type = types[whatis(val)];
            if(type === 3) {
                val = orderedStringify(val, fn);
            } else if(type === 2) {
                val = arrayStringify(val, fn);
            } else if(type === 1) {
                val = '"'+val+'"';
            }
    
            if(type !== 4)
                res += '"'+props[i]+'":'+ val+',';
        }
    
        return res.substring(res, res.lastIndexOf(','))+'}';
    };
    
    //orderedStringify for array containing objects
    var arrayStringify = function(a, fn) {
        var res = '[';
        for(var i = 0; i < a.length; i++) {
            var val = a[i];
            var type = types[whatis(val)];
            if(type === 3) {
                val = orderedStringify(val, fn);
            } else if(type === 2) {
                val = arrayStringify(val);
            } else if(type === 1) {
                val = '"'+val+'"';
            }
    
            if(type !== 4)
                res += ''+ val+',';
        }
    
        return res.substring(res, res.lastIndexOf(','))+']';
    }
    
    0 讨论(0)
  • 2020-11-30 05:25

    Using Underscore or Lodash:

    var sortByKeys = function(obj) {
      if (!_.isObject(obj)) {
        return obj;
      }
      var sorted = {};
      _.each(_.keys(obj).sort(), function(key) {
        sorted[key] = sortByKeys(obj[key]);
      });
      return sorted;
    };
    
    var sortedStringify = function() {
        arguments[0] = sortByKeys(arguments[0]);
        return JSON.stringify.apply(this, arguments);
    };
    

    Works in latest Chrome and Firefox.

    JSFiddle here: http://jsfiddle.net/stchangg/ruC22/2/

    0 讨论(0)
提交回复
热议问题