Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes bugs in bitwise operations #350

Merged
merged 2 commits into from
Jan 24, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,20 @@ Describe 'Binary Operators' {
)

process {
if ($To -ne 'String') {
if ($BinaryString -match '_') {
return 'Cannot convert this value!'
}

if ($To -ne 'ASCIIString') {
$BinaryString = $BinaryString -replace ' '
}

switch ($To) {
'Byte' { [Convert]::ToByte($BinaryString, 2) }
'SByte' { [Convert]::ToSByte($BinaryString, 2) }
'Int16' { [Convert]::Int16($BinaryString, 2) }
'Int16' { [Convert]::ToInt16($BinaryString, 2) }
'Int32' { [Convert]::ToInt32($BinaryString, 2) }
'Int64' { [Convert]::ToInt64($BinaryString, 2) }
'ASCIIString' {
[Char[]]$characters = foreach ($value in $BinaryString -split ' ') {
[Convert]::ToByte($value, 2)
Expand Down Expand Up @@ -204,7 +209,23 @@ Describe 'Binary Operators' {
$Value = '00000011' | ConvertFrom-Binary
$Result = '________' | ConvertFrom-Binary

-bnot $Value | Should -Be $Result
<#
The binary operators will, when given smaller value return a 32-bit integer. GetType can show this:

(-bnot $Value).GetType()

This can make the result of the operation below confusing. When written in binary, the result is
similar to:

11111111 11111111 11111111 ________

-band can be used to mask the result, limiting the possible result to a single byte.

11111111 11111111 11111111 ________
-band 00000000 00000000 00000000 11111111
#>
Comment on lines +217 to +226
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mismatched indentation looks a bit funny 😁

Also, wow that's confusing as all hell. Even with a specific byte-type input it still upcasts to int32... I'm sure that's probably a .NET thing, but... damn.


-bnot $Value -band 255 | Should -Be $Result
}
}

Expand Down Expand Up @@ -348,7 +369,7 @@ Describe 'Binary Operators' {
$Bytes[3]
) | Measure-Object -Sum

$Value.Sum | Should -Be 1652126821
$Value.Sum | Should -Be 1075843080
-join $BinaryValues | ConvertFrom-Binary -To Int32 | Should -Be $Value.Sum
}
}
Expand Down Expand Up @@ -391,7 +412,7 @@ Describe 'Binary Operators' {
It 'uses the most significant bit to describe a negative number' {
# When the signing bit alone is set, the value is the smallest value, -128.

'1000000' | ConvertFrom-Binary -To SByte | Should -Be (-128)
'10000000' | ConvertFrom-Binary -To SByte | Should -Be (-128)

# The opposite binary value is the maximum positive value for the number.

Expand Down Expand Up @@ -462,7 +483,7 @@ Describe 'Binary Operators' {

$Date = [DateTime]::FromFileTime(($BinaryValue | ConvertFrom-Binary -To Int64))

$Date | Should -Be '01 January 1601 00:02:45'
$Date.ToString('dd MMMM yyyy HH:mm:ss') | Should -Be '01 January 1601 00:02:45'
}
}

Expand All @@ -474,24 +495,34 @@ Describe 'Binary Operators' {
If a value is Big Endian, the largest value, the "big end", is first.

If a value is Little Endian, the largest value is last.

The endian order returned by the .NET types used below is dependent on the processor architecture.
Most modern systems use Little Endian ordering.

The section below assumes the processor and operating system are Little Endian.
#>

It 'might use a different byte order' {
# The significance assigned to each bit can dramatically change the value.

$BinaryValue = '________ ________ ________ ________'

# The value below is the result if the value is Big Endian.
# The value below is the result if the binary string is considered to be Big Endian.

$BinaryValue | ConvertFrom-Binary -To Int32 | Should -Be 1652126821
$BinaryValue | ConvertFrom-Binary -To ASCIIString | Should -Be 'byte'

# This can be explored forindividual bytes, by setting all others to 0. For example:

'________ 00000000 00000000 00000000' | ConvertFrom-Binary -To Int32 | Should -Be 1644167168
'00000000 00000000 00000000 ________' | ConvertFrom-Binary -To Int32 | Should -Be 101

<#
The Convert type used to change the value from binary expects the order
The Convert type used to change the value from a binary string expects the order
to be Big Endian.

To convert Little Endian to Big Endian the order of the values must be
reversed.
The command below takes the binary string and turns it into an array of bytes. Because the string
is in Big Endian order the bytes will be too.
#>

$Bytes = $BinaryValue -split ' ' | ConvertFrom-Binary
Expand All @@ -500,24 +531,26 @@ Describe 'Binary Operators' {
The BitConverter type has a number of static methods which can be used to create a value from a
series of bytes.

Like the Convert type, BitConverter expects to deal with Big Endian values.
BitConverter expects bytes to be in Little Endian order.
#>

# The bytes are in reverse order. Least significant first.
[Array]::Reverse($Bytes)

# Convert byte sequence to Int32, starting from the first byte
[BitConverter]::ToInt32($Bytes, 0) | Should -Be 1702132066

# To produce the same value as the original the array of bytes must be reversed.

[Array]::Reverse($Bytes)
[BitConverter]::ToInt32($Bytes, 0) | Should -Be 1652126821
}

It 'The IPAddress type can be used to change the order of a byte sequence' {
<#
IP Addresses in network packets are normally transmitted in Little Endian order.
Many values in network packets are transmitted in Big Endian order. An IP address, for example, is
transmitted as a single unsigned 32-bit integer.

An operating system might need to convert from Little Endian to Big Endian, or from
Big Endian to Little Endian.
An operating system might need to convert from Big Endian to Little Endian, or from
Little Endian to Big Endian.

The IPAddress class has two static methods available to change the Endian order of a value.
The IPAddress type has two static methods available to change the Endian order of a value.

[IPAddress] | Get-Member -Static

Expand Down