www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Convert binary to UUID from LDAP

reply Alexander Zhirov <azhirov1991 gmail.com> writes:
I get `objectGUID` data from LDAP as binary data. I need to 
convert `ubyte[]` data into a readable `UUID`. As far as I 
understand, it is possible to do this via `toHexString()`, but I 
have reached a dead end. Is there a way to make it more elegant, 
like [this 
technique](https://dlang.org/phobos/std_uuid.html#.UUID)?

```
ubyte[] => [159, 199, 22, 163, 13, 74, 145, 73, 158, 112, 7, 192, 
12, 193, 7, 194]
hex     => 9FC716A30D4A91499E7007C00CC107C2
```
Mar 27 2023
next sibling parent reply novice2 <sorryno em.ail> writes:
On Monday, 27 March 2023 at 17:56:22 UTC, Alexander Zhirov wrote:
 I get `objectGUID` data from LDAP as binary data. I need to 
 convert `ubyte[]` data into a readable `UUID`. As far as I 
 understand, it is possible to do this via `toHexString()`, but 
 I have reached a dead end. Is there a way to make it more 
 elegant, like [this 
 technique](https://dlang.org/phobos/std_uuid.html#.UUID)?

 ```
 ubyte[] => [159, 199, 22, 163, 13, 74, 145, 73, 158, 112, 7, 
 192, 12, 193, 7, 194]
 hex     => 9FC716A30D4A91499E7007C00CC107C2
 ```
https://run.dlang.io/is/JP01aZ ``` void main(){ import std.stdio: writeln; import std.format: format; ubyte[] a = [159, 199, 22, 163, 13, 74, 145, 73, 158, 112, 7, 192, 12, 193, 7, 194]; string b = format("%(%.2X%)",a); writeln(b); } ```
Mar 27 2023
parent reply Alexander Zhirov <azhirov1991 gmail.com> writes:
On Monday, 27 March 2023 at 18:33:46 UTC, novice2 wrote:
 https://run.dlang.io/is/JP01aZ

     ```
     void main(){
         import std.stdio: writeln;
         import std.format: format;
         ubyte[] a = [159, 199, 22, 163, 13, 74, 145, 73, 158, 
 112, 7, 192, 12, 193, 7, 194];
         string b = format("%(%.2X%)",a);
         writeln(b);
     }
     ```
Yes, the same result. I probably didn't write my post quite correctly. I mean get the UUID data type itself. Just using [this example](https://dlang.org/phobos/std_uuid.html#.UUID) `cast(ubyte[16])ubyte[]` will not work, conversion error.
Mar 27 2023
parent reply Alexander Zhirov <azhirov1991 gmail.com> writes:
On Monday, 27 March 2023 at 18:39:19 UTC, Alexander Zhirov wrote:
I mean get the UUID data type itself. Just using
 [this example](https://dlang.org/phobos/std_uuid.html#.UUID) 
 `cast(ubyte[16])ubyte[]` will not work, conversion error.
```d writeln(toHexString(cast(ubyte[])value.attributes["objectGUID"][0])); ``` When converting to HEX, I get the string `121F4C264DED5E41A33F445B0A1CAE32`, in which some values are reversed. I found ways on the Internet to transform the permutation method into the desired result, but most likely it will be a crutch rather than the right solution to lead to the final result `264c1f12-ed4d-415e-a33f-445b0a1cae32`.
Mar 27 2023
next sibling parent Kagamin <spam here.lot> writes:
This guid is (int,short,short,byte[8]) in little endian byte 
order. So if you want to convert it to big endian, you'll need to 
swap bytes in those int and two shorts.
```
ubyte[] guid=...
int* g1=cast(int*)guid.ptr;
*g1=bswap(*g1);
```
Mar 28 2023
prev sibling next sibling parent reply Alexander Zhirov <azhirov1991 gmail.com> writes:
On Tuesday, 28 March 2023 at 05:26:08 UTC, Alexander Zhirov wrote:
 When converting to HEX, I get the string 
 `121F4C264DED5E41A33F445B0A1CAE32`, in which some values are 
 reversed. I found ways on the Internet to transform the 
 permutation method into the desired result, but most likely it 
 will be a crutch rather than the right solution to lead to the 
 final result `264c1f12-ed4d-415e-a33f-445b0a1cae32`.
So far it has been possible to convert like this ```d { writeln(value.attributes["objectGUID"][0].toUUID); } UUID toUUID(const char[] objectGUID) { if(objectGUID.length != 16) throw new Exception("objectGUID does not match the length"); auto arr = (cast(ubyte[])objectGUID).array; auto part1 = arr[0 .. 4].reverse; auto part2 = arr[4 .. 6].reverse; auto part3 = arr[6 .. 8].reverse; auto part4 = arr[8 .. 10]; auto part5 = arr[10 .. $]; string hex = toHexString(part1) ~ '-' ~ toHexString(part2) ~ '-' ~ toHexString(part3) ~ '-' ~ toHexString(part4) ~ '-' ~ toHexString(part5); return cast(UUID)hex; } ```
Mar 28 2023
parent Alexander Zhirov <azhirov1991 gmail.com> writes:
On Tuesday, 28 March 2023 at 08:15:03 UTC, Alexander Zhirov wrote:
 So far it has been possible to convert like this
The idea was borrowed from [here](https://elixirforum.com/t/using-active-directory-guid-with-ecto-uuid-field/15904).
Mar 28 2023
prev sibling parent reply Kagamin <spam here.lot> writes:
This guid is (int,short,short,byte[8]) in little endian byte 
order. So if you want to convert it to big endian, you'll need to 
swap bytes in those int and two shorts.
```
ubyte[] guid=...
int* g1=cast(int*)guid.ptr;
*g1=bswap(*g1);
```
Mar 28 2023
parent Alexander Zhirov <azhirov1991 gmail.com> writes:
On Tuesday, 28 March 2023 at 13:18:59 UTC, Kagamin wrote:
 This guid is (int,short,short,byte[8]) in little endian byte 
 order. So if you want to convert it to big endian, you'll need 
 to swap bytes in those int and two shorts.
 ```
 ubyte[] guid=...
 int* g1=cast(int*)guid.ptr;
 *g1=bswap(*g1);
 ```
Yes, therefore, my option remains more correct rather than directly converting to UUID, since it does not correspond to the value specified in LDAP. Therefore, it is necessary to do byte permutations.
Mar 28 2023
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 3/27/23 1:56 PM, Alexander Zhirov wrote:
 I get `objectGUID` data from LDAP as binary data. I need to convert 
 `ubyte[]` data into a readable `UUID`. As far as I understand, it is 
 possible to do this via `toHexString()`, but I have reached a dead end. 
 Is there a way to make it more elegant, like [this 
 technique](https://dlang.org/phobos/std_uuid.html#.UUID)?
 
 ```
 ubyte[] => [159, 199, 22, 163, 13, 74, 145, 73, 158, 112, 7, 192, 12, 
 193, 7, 194]
 hex     => 9FC716A30D4A91499E7007C00CC107C2
 ```
auto uuid = UUID(*cast(ubyte[16]*)youruuiddata.ptr); -Steve
Mar 27 2023
parent reply Alexander Zhirov <azhirov1991 gmail.com> writes:
On Tuesday, 28 March 2023 at 00:51:43 UTC, Steven Schveighoffer 
wrote:
 auto uuid = UUID(*cast(ubyte[16]*)youruuiddata.ptr);
```d ubyte[] arr = cast(ubyte[])value.attributes["objectGUID"][0].dup; writeln(UUID(cast(ubyte[16])arr.ptr)); ``` `Error: cannot cast expression 'cast(ubyte*)arr' of type 'ubyte*' to 'ubyte[16]'` No, it's not possible to transform. The array is initially `immutable(char[])`.
Mar 27 2023
next sibling parent Jacob Shtokolov <jacob.100205 gmail.com> writes:
On Tuesday, 28 March 2023 at 05:05:58 UTC, Alexander Zhirov wrote:
 `Error: cannot cast expression 'cast(ubyte*)arr' of type 
 'ubyte*' to 'ubyte[16]'`
Here is the working example: ```d import std.stdio; import std.uuid; void main() { ubyte[] arr = [159, 199, 22, 163, 13, 74, 145, 73, 158, 112, 7, 192, 12, 193, 7, 194]; UUID(arr[0 .. 16]).writeln; } ``` You just need to take a slice of your array to guarantee that it has only 16 elements, and thus, pass it to `UUID`.
Mar 28 2023
prev sibling next sibling parent reply WebFreak001 <d.forum webfreak.org> writes:
On Tuesday, 28 March 2023 at 05:05:58 UTC, Alexander Zhirov wrote:
 On Tuesday, 28 March 2023 at 00:51:43 UTC, Steven Schveighoffer 
 wrote:
 auto uuid = UUID(*cast(ubyte[16]*)youruuiddata.ptr);
```d ubyte[] arr = cast(ubyte[])value.attributes["objectGUID"][0].dup; writeln(UUID(cast(ubyte[16])arr.ptr)); ``` `Error: cannot cast expression 'cast(ubyte*)arr' of type 'ubyte*' to 'ubyte[16]'` No, it's not possible to transform. The array is initially `immutable(char[])`.
the formatting messed up here. Try this code: ```d auto uuid = UUID( (cast(const(ubyte)[]) value.attributes["objectGUID"][0]) [0 .. 16] ); ``` no need to `.dup` the values - UUID can work without manipulating the original data, so we just need to cast the `immutable(char)[]` to `const(ubyte)[]` The LDAP library should probably really instead expose `ubyte[]` instead of `string`
Mar 28 2023
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 3/28/23 6:36 AM, WebFreak001 wrote:

 the formatting messed up here. Try this code:
 
 ```d
 auto uuid = UUID(
      (cast(const(ubyte)[]) value.attributes["objectGUID"][0])
      [0 .. 16]
 );
 ```
Nice, I didn't think this would work actually! -Steve
Mar 28 2023
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 3/28/23 1:05 AM, Alexander Zhirov wrote:
 On Tuesday, 28 March 2023 at 00:51:43 UTC, Steven Schveighoffer wrote:
 `auto uuid = UUID(*cast(ubyte[16]*)youruuiddata.ptr);` (added quotes here)
```d ubyte[] arr = cast(ubyte[])value.attributes["objectGUID"][0].dup; writeln(UUID(cast(ubyte[16])arr.ptr)); ``` `Error: cannot cast expression 'cast(ubyte*)arr' of type 'ubyte*' to 'ubyte[16]'` No, it's not possible to transform. The array is initially `immutable(char[])`.
Apologies, I quoted my original above to suppress the markdown formatting. Here it is again with syntax highlighting. ```d auto uuid = UUID(*cast(ubyte[16]*)youruuiddata.ptr); ``` That should work. I sometimes forget that my newsreader adds the markdown tag, even though it looks good on my end. -Steve
Mar 28 2023