Search code examples
active-directoryoctetstring

How are binary octet string converted from binary to guid?


In Active Directory, I see that objectGUID are octet string binary 16 bytes fields. How is this conversion happening?

Is the binary converted to octetstring by splitting the fields in chunks? Like a Uint8Array?

How does it eventually become something like:

{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} 

Solution

  • I just had to do this myself and found a PowerShell snippet that I had from over a decade ago, I tested it today and it still works.

    The first line of code removes the backlash character in case your octet string is in the following format: '\bb\85\43\3e\43\7c\eb\4f\8e\a2\97\c6\5c\c0\6a\bf'

    Input: $OctetString = '\bb\85\43\3e\43\7c\eb\4f\8e\a2\97\c6\5c\c0\6a\bf'

    Output: '3e4385bb-7c43-4feb-8ea2-97c65cc06abf'

    {
        $OctetString = ($OctetString -replace '\\', '')
    
        [UInt32]$a = [Convert]::ToUInt32(($OctetString.Substring(6, 2) + $OctetString.Substring(4, 2) + $OctetString.Substring(2, 2) + $OctetString.Substring(0, 2)), 16)
        [UInt16]$b = [Convert]::ToUInt16(($OctetString.Substring(10, 2) + $OctetString.Substring(8, 2)), 16)
        [UInt16]$c = [Convert]::ToUInt16(($OctetString.Substring(14, 2) + $OctetString.Substring(12, 2)), 16)
        [Byte]$d = ([Convert]::ToUInt16($OctetString.Substring(16, 2), 16) -as [byte])
        [Byte]$e = ([Convert]::ToUInt16($OctetString.Substring(18, 2), 16) -as [byte])
        [Byte]$f = ([Convert]::ToUInt16($OctetString.Substring(20, 2), 16) -as [byte])
        [Byte]$g = ([Convert]::ToUInt16($OctetString.Substring(22, 2), 16) -as [byte])
        [Byte]$h = ([Convert]::ToUInt16($OctetString.Substring(24, 2), 16) -as [byte])
        [Byte]$i = ([Convert]::ToUInt16($OctetString.Substring(26, 2), 16) -as [byte])
        [Byte]$j = ([Convert]::ToUInt16($OctetString.Substring(28, 2), 16) -as [byte])
        [Byte]$k = ([Convert]::ToUInt16($OctetString.Substring(30, 2), 16) -as [byte])
    
        [Guid]$guid = New-Object Guid($a, $b, $c, $d, $e, $f, $g, $h, $i, $j, $k)
        return $guid.Guid
    }
    

    In case you want to convert the other direction:

    Input: $guid= '3e4385bb-7c43-4feb-8ea2-97c65cc06abf'

    Output: '\bb\85\43\3e\43\7c\eb\4f\8e\a2\97\c6\5c\c0\6a\bf'

    {
        $stringGuid = [Guid]"{$guid}"
        $octetGuid = $null
        foreach ($byte in $stringGuid.ToByteArray()) {
            $octetGuid += '\' + $byte.ToString('x2')
        }
        return $octetGuid
    }