Можно ли преобразовать байтовый массив в 8-битный целочисленный массив со знаком в Powershell? - PullRequest
1 голос
/ 04 февраля 2020

Я пытаюсь преобразовать шестнадцатеричную строку в массив целых чисел со знаком 8 бит в Powershell.

Я использую следующую функцию для преобразования шестнадцатеричной строки, такой как A591BF86E5D7D9837EE7ACC569C4B59B, в байтовый массив, который мне затем нужно преобразовать в 8-разрядный целочисленный массив со знаком.

Function GetByteArray {

    [cmdletbinding()]

    param(
        [parameter(Mandatory=$true)]
        [String]
        $HexString
    )

    $Bytes = [byte[]]::new($HexString.Length / 2)

    For($i=0; $i -lt $HexString.Length; $i+=2){
        $Bytes[$i/2] = [convert]::ToByte($HexString.Substring($i, 2), 16)
    }

    $Bytes  
}

После использования функции шестнадцатеричный код преобразуется в байтовый массив, такой как этот:

unsigned byte array

Мне нужно взять массив без знака и преобразовать o в 8 бит байтовый массив со знаком, как показано ниже:

signed 8-bit integer array (byte array)

Возможно ли это? Если так, как это может быть реализовано?

Я пытался использовать класс BitConverter, но, насколько я видел, он может конвертировать только в int16.

Заранее спасибо

1 Ответ

5 голосов
/ 04 февраля 2020

Чтобы получить массив [byte[]] ([byte] == System.Byte, без знака 8-битный целочисленный тип):

$hexStr = 'A591BF86E5D7D9837EE7ACC569C4B59B' # sample input

[byte[]] ($hexStr -split '(.{2})' -ne '' -replace '^', '0X')
  • -split '(.{2})' разбивает входную строку по 2-символьным последовательностям, а включение в (...) приводит к тому, что эти последовательности включают в возвращаемые токены; -ne '' затем отсеивает пустых токенов (которые технически являются фактическими токенами данных).

  • -replace , '^', '0X' ставит префикс 0X перед каждым полученным 2- hex-di git строка, выходной массив '0XA5', '0X91', ...

  • приведение результата к [byte[]] услужливо распознает этот шестнадцатеричный формат напрямую.

    • Примечание: Если вы забудете приведение, вы получите массив строк .

Чтобы получить массив [sbyte[]] ( [sbyte] == System.SByte, со знаком 8-битное целое), приведение непосредственно к [sbyte[]] вместо ; не попробуйте объединить составы: [sbyte[]] [byte[]] (...))


Если вы дали a [byte[]] массив, который вы затем хотите преобразовать в [sbyte[]], используйте следующее (возможны более эффективные подходы):

[byte[]] $bytes = 0x41, 0xFF # sample input; decimal: 65, 255

# -> [sbyte] values of:  65, -1
[sbyte[]] $sBytes = ($bytes.ForEach('ToString', 'X') -replace '^', '0X')

Применено к вашим выборочным значениям в десятичной записи:

# Input array of [byte]s.
[byte[]] $bytes = 43, 240, 82, 109, 185, 46, 111, 8, 164, 74, 164, 172
# Convert to an [sbyte] array.
[sbyte[]] $sBytes = ($bytes.ForEach('ToString', 'X') -replace '^', '0X')
$sBytes # Output (each signed byte prints on its own line, in decimal form).

Вывод:

43
-16
82
109
-71
46
111
8
-92
74
-92
-84
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...