Another Way to Show Bitwise Operation Results

This is something that came to me as I was working to do some bitwise operations for a project that had a lot of pInvoke stuff and required that I do some shifting of bits. Being that I wasn’t all that familiar with this (I’m more familiar with BOR, BAND and XOR), I wanted to learn more about the before and after of the binary representation of the data.

What is a bitwise operation you ask? Well, it is

a bitwise operation operates on one or more bit patterns or binary numerals at the level of their individual bits. It is a fast, primitive action directly supported by the processor, and is used to manipulate values for comparisons and calculations. –From Wikipedia Article on Bitwise Operations

I decided that it would be nice to have a function that would allow you to provide the parameters needed for a bitwise operation, but rather than just outputting a value as a result of the operation, it would instead show you more information about the results such as showing the values in binary and hex form. But that wasn’t all I wanted. I saw the about_Comparison_Operators help file and liked the examples that they showed when doing an operation.

image

Putting this all together led me to a function I wrote called Invoke-BitwiseOperation which accepts a –First and –Second parameter which is for the two values, a –BitwiseOperator parameter that accepts the following values: BAND,BOR,BXOR,BNOT,SHL,SHR and finally there is the –Graphical parameter which gives you the output like you see in the help files.

I start out by using a helper function called ConvertToBinary which takes an integer, converts it to a binary form and then uses a RegEx pattern to split out the binary data into chunks of 8.

Function ConvertToBinary {
    Param(
        [parameter(ValueFromPipeline=$True)]
        $Item
    )
    Process {
        $String = [Convert]::ToString($Item,2)
        $Reverse = -join (-join $string[$String.length..0] -split '(?<=\G.{8})').PadRight(8,'0')
        -join $Reverse[$Reverse.length..0] -split '(?<=\G.{8})'
    }
}

(8956 | ConvertToBinary) -join ' '

bitwise_2

I opted to not join the output prior so I could do some more stuff with the collection of values later on in my code.

If ($BitWiseOperator -eq 'BNOT') {
    $Result = [Math]::Abs((Invoke-Expression "-$($BitWiseOperator) $($First)"))
} Else {
    If ($PSBoundParameters.ContainsKey('First') -AND $PSBoundParameters.ContainsKey('Second')){
        $Result = Invoke-Expression "$($First) -$($BitWiseOperator) $($Second)"
    } Else {
        Write-Warning "You must specify both a First and Second parameter!"
        BREAK
    }
}
$First_Bin = $First | ConvertToBinary
$First_Hex = "0x{0:x}" -f $First
If ($PSBoundParameters.ContainsKey('Second') -AND $BitWiseOperator -notmatch 'SHL|SHR') {
    $Second_Bin = $Second | ConvertToBinary
    $Second_Hex = "0x{0:x}" -f $Second
}
$Result_Bin = $Result | ConvertToBinary   
$Result_Hex = "0x{0:x}" -f $Result

This portion looks at what kind of Bitwise operator that I specified and takes an action based on that, such as when using BNOT. I also perform the conversion of the values to binary and also convert the data to hex for later use.

If ($PSBoundParameters.ContainsKey('Graphical')) {
    $Padding = '00000000'
    $FirstList = New-Object System.Collections.ArrayList
    $SecondList = New-Object System.Collections.ArrayList
    $ResultList = New-Object System.Collections.ArrayList

    $FirstHex = "0x{0:x}" -f $First
    $SecondHex = "0x{0:x}" -f $Second
    $ResultHex = "0x{0:x}" -f $Result
 
    $First_Bin | ForEach {
        [void]$FirstList.Add($_)
    }
    $Second_Bin | ForEach {
        [void]$SecondList.Add($_)
    }
    $Result_Bin | ForEach {
        [void]$ResultList.Add($_)
    }
   


    $Count = $FirstList, $SecondList, $ResultList | ForEach {
        [pscustomobject]@{
            Count = $_.count
        }
    } | Sort Count -Descending | Select -First 1 -ExpandProperty Count
 
    $FirstList, $SecondList, $ResultList | ForEach {
        $ToPad = $Count - $_.Count
        If ($ToPad -gt 0) {                
            For ($i=1; $i -le $ToPad; $i++) {
                $_.Insert(0,$Padding)
            }
        }
    }
 
    $Line = '-' * (($ResultList -join ' ').Length)
 
 
    "$($FirstList -join ' ')  ($First, $($FirstHex)"
    If ($BitWiseOperator -notmatch 'BNOT|SHL|SHR') {
        "$($SecondList -join ' ')  ($Second, $($SecondHex)"
    }
    "$line  $BitWiseOperator"
    "$($ResultList -join ' ')  ($result, $($ResultHex)"
 
} Else {
    [pscustomobject]@{
        First = $First
        First_Bin = $First_Bin
        First_Hex = $First_Hex
        BitWiseOperator = $BitWiseOperator
        Second = $Second
        Second_Bin = $Second_Bin
        Second_Hex = $Second_Hex
        Result = $Result
        Result_Bin = $Result_Bin
        Result_Hex = $Result_Hex
    }
}

The final portion of the script takes a turn based on if the –Graphical parameter is used or not. If used, some more data processing occurs so it can display the data like what you saw in the help file. Otherwise, it just outputs an object with the converted values. Some examples are shown below.

Invoke-BitWiseOperation -First 32 -Second 16 -BitWiseOperator SHL –Graphical

BitWiseDemo2

Invoke-BitWiseOperation -First 7 -BitWiseOperator BNOT

Bitwise_demo

Download Invoke-BitwiseOperation

https://gallery.technet.microsoft.com/scriptcenter/Invoke-BitwiseOperation-bc2f3c80

About Boe Prox

Microsoft Cloud and Datacenter MVP working as a SQL DBA.
This entry was posted in powershell and tagged , , , . Bookmark the permalink.

5 Responses to Another Way to Show Bitwise Operation Results

  1. erousseau77 says:

    Reblogged this on Augmented ITC Blog.

  2. PickUp says:

    How can I interpretate ConvertToBinary function?

    PS > [convert]::ToString(8956,2)
    10001011111100
    PS > (8956 | ConvertToBinary) -join ‘ ‘
    10001011 00111100
    PS > [convert]::ToInt32(1000101100111100,2)
    35644
    PS > [convert]::ToInt32(10001011111100,2)
    8956

    • Boe Prox says:

      I had some wackiness happening with that function and have fixed how I was creating the binary value. It should be a lot more accurate now.

  3. PickUp says:

    PS > -bnot 7
    -8

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s