Packed GUIDs and Darwin Descriptors

A packed GUID can be obtained by transforming a standard GUID in the following way:

1 remove the curly braces and separating dashes from a standard GUID;

2 write the first three groups of hexadecimal characters in a standard GUID in reverse order;

3 switch every two characters in the fourth and fifth group in a standard GUID.

This constructs a well-known Darwin Descriptor, which is a combination of the product code GUID, a feature name, and a component code GUID.

String manipulation steps:

Action Original GUID section Packed GUID Section
Reverse first 8 characters 12345678 87654321
Reverse next 4 characters ABCD DCBA
Reverse next 4 characters WXYZ ZYXW
Reverse next 2 characters 12 21
Reverse next 2 characters 34 43
Reverse next 2 characters AB BA
Reverse next 2 characters CD DC
Reverse next 2 characters EF FE
Reverse next 2 characters GH HG
Reverse next 2 characters IJ JI
Reverse next 2 characters KL LK

Recombine characters without any curly braces or hyphens to see your packed GUID:
87654321DCBAZYXW2134BADCFEHGJILK

Uncompressed GUID (standard): {12345678-ABCD-WXYZ-1234-ABCDEFGHIJKL}
Compressed GUID: 87654321DCBAZYXW2134BADCFEHGJILK

 

But what about reversing a Packed GUID?

A sample I came across some time ago…  Sorry, I wish I could give the author credit but I do not know where this came from.

private static string TranslateMsiProductCode(Guid productCode)
{
    //  93 CE EF F6   AA 3D  4E 99   84 E1 8F FB F7 2C 43 0D  <--- Source
    //  6F FE EC 39   D3 AA  99 E4   48 1E F8 BF 7F C2 34 D0  <--- Target
    //  -----------   -----  -----   -----------------------
    //  01 23 45 67   89 01  23 45   67 89 01 23 45 67 89 01
    //  0                1                 2              3

    // examples:
    // {93CEEFF6-AA3D-4E99-84E1-8FFBF72C430D} -> 6FFEEC39D3AA99E4481EF8BF7FC234D0
    // {0E837AF0-4C92-4077-83F0-D022073F17C0} -> 0FA738E029C47704380F0D2270F3710C
    // {4AE61EA4-9F6F-4616-9035-0CF343EA462D} -> 4AE16EA4F6F961640953C03F34AE64D2


    string input = productCode.ToString("N").ToUpper();
    StringBuilder newString = new StringBuilder(input);

    newString[0] = input[7];
    newString[1] = input[6];
    newString[2] = input[5];
    newString[3] = input[4];
    newString[4] = input[3];
    newString[5] = input[2];
    newString[6] = input[1];
    newString[7] = input[0];

    newString[8] = input[11];
    newString[9] = input[10];
    newString[10] = input[9];
    newString[11] = input[8];

    newString[12] = input[15];
    newString[13] = input[14];
    newString[14] = input[13];
    newString[15] = input[12];

    newString[16] = input[17];
    newString[17] = input[16];
    newString[18] = input[19];
    newString[19] = input[18];
    newString[20] = input[21];
    newString[21] = input[20];
    newString[22] = input[23];
    newString[23] = input[22];
    newString[24] = input[25];
    newString[25] = input[24];
    newString[26] = input[27];
    newString[27] = input[26];
    newString[28] = input[29];
    newString[29] = input[28];
    newString[30] = input[31];
    newString[31] = input[30];

    return newString.ToString();
}

Leave a Reply

Your email address will not be published. Required fields are marked *