Skip to content

Unexpected/incompatible byte representation #503

Closed
@bjornharrtell

Description

@bjornharrtell

I can roundtrip GUID 75b097d1-b891-4834-9b12-4a94d8c42504 with the following node repl code:

> const uuid = require('uuid')
> uuid.parse('75b097d1-b891-4834-9b12-4a94d8c42504')
Uint8Array(16) [
  117, 176, 151, 209, 184,
  145,  72,  52, 155,  18,
   74, 148, 216, 196,  37,
    4
]
> const a = uuid.parse('75b097d1-b891-4834-9b12-4a94d8c42504')
undefined
> uuid.stringify(a)
'75b097d1-b891-4834-9b12-4a94d8c42504'

But I suspect the byte representation is not as expected. I would expect the byte array to be [209, 151, 176, 117, 145, 184, 52, 72, 155, 18, 74, 148, 216, 196, 37, 4]. I found a gist at https://gist.github.com/daboxu/4f1dd0a254326ac2361f8e78f89e97ae that produces that array from 75b097d1-b891-4834-9b12-4a94d8c42504 and it's also what is produced by fx. C# / .NET.

Activity

bjornharrtell

bjornharrtell commented on Aug 3, 2020

@bjornharrtell
Author

I now understand that [209, 151, 176, 117, 145, 184, 52, 72, 155, 18, 74, 148, 216, 196, 37, 4] is the mixed-endian encoded variant which I suppose is not supported by this package.

ctavan

ctavan commented on Aug 3, 2020

@ctavan
Member

@bjornharrtell wow, thanks for reporting!

I think we should mention that in the documentation. Reference: https://stackoverflow.com/a/45671539/1053532

reopened this on Aug 3, 2020
added 2 commits that reference this issue on Aug 3, 2020
f4a58fe
63716c0
broofa

broofa commented on Aug 3, 2020

@broofa
Member

That's an interesting internal data structure MSFT is using to represent GUIDs. It's strange they use multi-byte ints for the first half of the bytes (int, short, short), but individual bytes for the second half. I assume it's because (per wikipedia) "The current version of the Microsoft guidgen tool produces standard variant-1 UUIDs.", where the timestamp is contained in the first half of the UUID.

However in most other GUIDs (versions 4 most notably, but also 3 and 5), time fields don't exist so the distinction between time and non-time fields in such a data structure is not meaningful. Thus, I believe the structure we're using - a simple byte array with order that corresponds to the UUID string ordering - is better suited for most purposes. It's version and platform neutral, and generally more intuitive.

(Put up a PR to explicitly document how bytes are ordered though.)

benrr101

benrr101 commented on Mar 7, 2021

@benrr101

I was confounded by this issue today. Not sure who's right here, but according to this SO answer the RFC states the int/short/short values should be stored in network byte order (ie, big-endian). If that's true, then I don't think the package is actually RFC compliant.

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

        Participants

        @bjornharrtell@broofa@ctavan@benrr101

        Issue actions

          Unexpected/incompatible byte representation · Issue #503 · uuidjs/uuid