Search code examples
c#.netpowershellbitarray

Creating Bit Array in Powershell/C# from integers


I'm trying to reverse engineer a game database and have come to a roadblock.

I can load all the tables/fields/records , however I'm stuck when it comes to converting the record values to hex or bits

the values (in game) are as follows: (15 bits) 192 - (10 bits) 20 - (5 bits) 19 - (5 bits) 2

In the db file , it shows 00 C0 - 00 0A - A6 - 00

This is strange , because only the first value (00 C0) is the same in Hex (192)

The other values are different , I'm guessing this is because they are not full bytes (10 and 5 bits respectively) so it must be using a bit array.

This guess is further proven when I change the final value from 2 , to 31. The last 2 values in the db are changed, and the hex string becomes 00 C0 - 00 0A - E6 - 07

So what's the best way to get these 4 integers in to a bit array in PowerShell so I can try to determine what's going on here ? If it is not obvious to any more experienced programmers what is at play here. If required I could also use C# however I'm less experienced.

Thanks


Solution

  • I am not sure what you want to achieve. 5bits words are literally odd. It could be that there is no clear conversion here but something like a hash. Anyways, you could technically count from 0 to 2^35 - 1 and poke that in your game and lookup the result in your database.

    Let me give you a few conversion methods:

    To bit array:

    $Bits = 
        [convert]::ToString(192, 2).PadLeft(15, '0') +
        [convert]::ToString( 20, 2).PadLeft(10, '0') +
        [convert]::ToString( 19, 2).PadLeft( 5, '0') +
        [convert]::ToString(  2, 2).PadLeft( 5, '0')
    
    $Bits
    00000001100000000000101001001100010
    

    And back:

    if ($Bits -Match '(.{15})(.{10})(.{5})(.{5})') {
        $Matches[1..4].Foreach{ [convert]::ToByte($_, 2) }
    }
    192
    20
    19
    2
    

    To Int64:

    $Int64 = [convert]::ToInt64($Bits, 2)
    
    $Int64
    201347682
    

    To bytes:

    $Bytes = [BitConverter]::GetBytes($Int64)
    
    [System.BitConverter]::ToString($Bytes)
    62-52-00-0C-00-00-00-00
    

    Note that the bytes list is reverse order:

    [convert]::ToString(0x62, 2)
    1100010