Skip to content

V8 serialize is not deterministic #2448

Description

@trueshura
  • node version v10.17.0:
  • Linux 4.19.19-041919-lowlatency #201901310331 SMP PREEMPT Thu Jan 31 08:37:07 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux:
  • npm version:
{ npm: '6.12.0',
  ares: '1.15.0',
  brotli: '1.0.7',
  cldr: '35.1',
  http_parser: '2.8.0',
  icu: '64.2',
  modules: '64',
  napi: '5',
  nghttp2: '1.39.2',
  node: '10.17.0',
  openssl: '1.1.1d',
  tz: '2019a',
  unicode: '12.1',
  uv: '1.28.0',
  v8: '6.8.275.32-node.54',
  zlib: '1.2.11' }

v8.serialize produce different output, still decodable but it's different bytes, and different length. it's matter for me.
same PC, same version.
just want to know: what cause that difference and how to avoid it.

const v8 = require('v8');

let data = {
    key: 'value',
    arrValue: [1,2,3,4],
    objValue: {
        nestedKey: 'value'
    }
};

const buffData = v8.serialize(data);
const dataCopy = v8.deserialize(buffData);

// it seems we still have same object
console.log(JSON.stringify(dataCopy) === JSON.stringify(data));

// but encoded buffer is different!
const buffEncoded = v8.serialize(Object.assign({}, dataCopy));
console.log(buffData.length !== buffEncoded.length);

console.log(buffData.toString('hex'));
console.log(buffEncoded.toString('hex'));

Activity

  1. trueshura commented on Jan 28, 2020

    @trueshura
    Author

    If you remove array element - it works like a charm again!
    i mean

    let data = {
        key: 'value',
        objValue: {
            nestedKey: 'value'
        }
    };
    

    encodes as expected

  2. addaleax commented on Jan 28, 2020

    @addaleax
    Member

    V8 uses different internal representations for some values, for example, Arrays in V8 can be dense or sparse, with special cases for integer arrays or floating-point-value arrays, and strings can have different internal representations as well, e.g. using UTF16 encoding or using ISO-8859-1.

    Generally, you can’t rely on the exact output from v8.serialize(), that’s correct. If it’s important to you to have deterministic output, it might not be the right tool for you.

  3. trueshura commented on Jan 28, 2020

    @trueshura
    Author

    V8 uses different internal representations for some values, for example, Arrays in V8 can be dense or sparse, with special cases for integer arrays or floating-point-value arrays, and strings can have different internal representations as well, e.g. using UTF16 encoding or using ISO-8859-1.

    it's ok, but i didn't expect diffrent output for "same" values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions