Сравнение расстояния Хэмминга с PowerShell - PullRequest
0 голосов
/ 20 ноября 2018

Как я могу сравнить 8 бит с другими 8 битами, чтобы получить что-то вроде этого:

first Nr     1 0 0 0 1 1 0 1
second Nr    1 0 1 0 1 0 0 0
Result       r r f r r f r f

r = right 
f = false

Спасибо

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Аннотированное решение:

$firstNrBin  = '1 0 0 0 1 1 0 1'
$secondNrBin = '1 0 1 0 1 0 0 0'

# Convert the binary number strings to [byte]s (unsigned 8-bit values).
$firstNr = [Convert]::ToByte($firstNrBin -replace ' ', 2)   # 141 == 0x8d
$secondNr = [Convert]::ToByte($secondNrBin -replace ' ', 2) # 168 == 0xa8

# Perform bitwise XOR logic and negate the result to get a bit field
# that reflects the bits where the input numbers match.
# Note the need use of -band 0xff to limit the result to 8 bits - see
# explanation below.
# -> 218 == 0xda = 11011010
$bitsInCommon = [byte] (-bnot ($firstNr -bxor $secondNr) -band 0xff)

# Convert the bit field back into a binary representation, 0-padded to 8 chars.
# -> '11011010'
$bitsInComminBin = [Convert]::ToString($bitsInCommon, 2).PadLeft(8, '0')

# Produce the desired output format with string manipulation
$result = ([char[]] $bitsInComminBin -replace '1', 'r' -replace '0', 'f') -join ' '

# Output the result
[ordered] @{
  'first Nr' = $firstNrBin
  'second Nr' = $secondNrBin
  'Result' = $result
}

Выше приведено:

Name                           Value
----                           -----
first Nr                       1 0 0 0 1 1 0 1
second Nr                      1 0 1 0 1 0 0 0
Result                         r r f r r f r f

Обратите внимание, что побитовые операторы PowerShell выводят [int] - System.Int32 в качественаименьший тип данных, т. е. число со знаком .

Поэтому вам необходимо явно маскировать дополнительные биты с помощью оператора -band, потому что непосредственное приведение обратно к unsigned тип не работает.

В данном случае:

$firstNr -bxor $secondNr # 141 -bxor 168

создает 37 как значение [int], то есть следующие 32 бита:

00000000000000000000000000100101

Применение -bnot к этому [int] дает побитовое дополнение:

11111111111111111111111111011010

Как [int], это отрицательное число, потому чтоустановлен старший бит: -38

Вы не можете привести его непосредственно к типу без знака, например [byte], чтобы получить только младшие 8 бит, но вы можете использовать -band с битовой маской 0xffобнулить все биты, кроме первых 8, - но учтите, что в этом случае результат все равно равен [int]:

-bnot -38 -band 0xff

дает следующеебиты:

00000000000000000000000000100101

Как [int], это 37, который вы можете безопасно вернуть обратно к [byte].

0 голосов
/ 20 ноября 2018

Вы можете использовать операторы побитового сравнения :

например.

[byte]$a = 9       #00001001
[byte]$b = 12      #00001100

-bnot ($a -bxor $b) #11111010

$a -band $b        #00001000
$a -bor $b         #00001101

Для вашего сценария вы смотрите на -bxor функциональность, принимая только отрицательный (-bnot) результат.


Если вам нужно увидеть сами флаги, вы можете использовать такие методы:

function Format-BooleanString {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [byte]$ByteToDisplay 
    )
    Process {
        [string]$result = ''
        for ([int]$i = 7; $i -ge 0; $i--) {
            [int]$x = [Math]::Pow(2, $i)
            if ($ByteToDisplay -band $x) {
                $result += '1'
            } else {
                $result += '0'
            }
        }
        $result
    }
}
function Convert-BooleanStringToByte {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string]$ByteAsString
    )
    Process {
        if ($ByteAsString -notmatch '^[01]{8}$') {
            throw 'Input string must be 8 chars, consisting of only 0s and/or 1s'
        }
        [int]$result = 0
        for ([int]$i = 0; $i -lt 8; $i++) {
            if ($ByteAsString[$i] -eq '1') {
                $result += [Math]::Pow(2, 7-$i)
            }
        }
        [byte]$result            
    }

}

Format-BooleanString -ByteToDisplay 9
Convert-BooleanStringToByte -ByteAsString '00100010'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...