3

I am trying to write a Python utility to convert from Oracle's RAW byte strings (as strings) to Guids and vice-versa. I am trying to re-use the algorithm from the same utility I built in C#, but constructing a Guid and a UUID from the same byte array yields different Guid's/UUID's. They are the same aren't they? I've read that UUID is just a better term.

In C# I have a byte array, byte_array that looks like this:

{byte[16]}
    [0]: 151
    [1]: 163
    [2]: 6
    [3]: 235
    [4]: 224
    [5]: 173
    [6]: 188
    [7]: 79
    [8]: 182
    [9]: 220
    [10]: 222
    [11]: 173
    [12]: 29
    [13]: 103
    [14]: 37
    [15]: 125

and in Python I have a byte array that looks like this:

array('B', [151, 163, 6, 235, 224, 173, 188, 79, 182, 220, 222, 173, 29, 103, 37, 125])

These two arrays clearly have the same content, yet in C#:

guid = new Guid(byte_array) -> guid == eb06a397-ade0-4fbc-b6dc-dead1d67257d

And in python:

guid = uuid.UUID(bytes=byte_array.tostring()) -> guid == 97a306eb-e0ad-bc4f-b6dc-dead1d67257d

I see that C#'s Guid(...) does some re-arranging of the byte order, while Python's UUID(...) leaves the byte order in the UUID the same as in the byte array.

The Python result is incorrect for converting Oracle's RAW byte strings, as my C# code that works (it is in production in hundreds of lines of code), shows the correct Guid for a byte array.

Is there any way I get a UUID/Guid from a byte array in Python that is the same as a C# Guid for the same byte array?

I have looked at the source for the C# Guid(byte[] bytes) ctor, and while it is a simple assignment to positions in a Guid, the positions in the Guid are 11 in number and are of types, int, short, and byte, which I don't have in Python, and I don't want to get into bitwise manipulation to emulate C# types in Python.

ProfK
  • 49,207
  • 121
  • 399
  • 775
  • 4
    Does this answer your question? [Is there any way to generate a UUID in Java that is identical to that of the one generated in C#?](https://stackoverflow.com/questions/45337638/is-there-any-way-to-generate-a-uuid-in-java-that-is-identical-to-that-of-the-one) Although it's about Java instead of Python, the "endianness" issue appears to be the root of your problem just the same. Take a look at indices 4 and 5 in the formatted output. You have `ade0` vs. `e0ad`. – madreflection Sep 14 '20 at 18:08
  • @madreflection Thanks, but no. The suggested Java code uses a `ByteBuffer` that I don't have in Python. – ProfK Sep 14 '20 at 18:19
  • 1
    Don't take the answer too literally. The `ByteBuffer` is just one means to that end. The takeaway from that answer is that the byte order of certain parts of the GUID is different depending on big- vs little-endian treatment of those parts. You have an array. Swap `[4]` with `[5]` and `[6]` with `[7]`, and reverse `[0]` through `[3]`. – madreflection Sep 14 '20 at 18:22

1 Answers1

2

Just came across this issue as well... Solved it by using the bytes_le parameter in the constructor instead of bytes:

uuid.UUID(bytes_le = bytes)
KW1
  • 21
  • 2