【问题标题】:Powershell Bytes to Bit ArrayPowershell 字节到位数组
【发布时间】:2016-11-17 19:47:27
【问题描述】:

我在将 ByteArrays 转换为 Bits 然后将它们带回来时遇到问题。最终我试图从 ByteArray 到 Hex 然后返回,但我得到的值与我输入的不同。

这是 BitArray 设置:

$list = @(1,7,10,11,13,14,15,16,17,18,19,20,21,22,23,29,30,32,33,37,39,41,42,43,44,46,48,49,54,56,60,69,72,74,77,79,88,98,100,102,104,109,114,116,118,119,120,127,128,129,133,135,143,147)
$BitArray = New-Object BitArray(152)
$list | % {$BitArray[$_ - 1] = $true}

注意:我正在使用一些自定义类型加速器

if ($(try{[accelerators]}catch{"nope"}) -eq "nope"){
  $xlr=[psobject].Assembly.GetType('System.Management.Automation.TypeAccelerators')
  $xlr::Add('accelerators',([psobject].Assembly.GetType('System.Management.Automation.TypeAccelerators')))
}
@{
  "datatable"="System.ComponentModel.MarshalByValueComponent"
  "marshal"="System.Runtime.InteropServices.Marshal"
  "BitArray"="System.Collections.BitArray"
}.GetEnumerator() | %{
  $AcceleratorName=$_.name
  $AcceleratorValue=$_.value
  if (-not ((([accelerators]::get).keys | ? {$_ -eq "$AcceleratorName"} | Measure-Object).count)){
    [accelerators]::add("$AcceleratorName","$AcceleratorValue")
  }
}

根据我的发现,我使用它来转换为字节:

$result =  New-Object System.Byte[] (19)
$BitArray.CopyTo($result, 0)

但是当我把它们都变成字符串时,它们不匹配。

字符串代码的输入:

$array = @()
0..151 | % {if ($BitArray[$_]) {$array += 1} else {$array += 0}}

$InputAsArray = @()
0..18 | % {
    $InputAsArray += ($array -join "").Substring(($_ * 8),8)
}

输出到字符串代码:

($result | % { [Convert]::ToString($_, 2).PadRight(8,'0')})

输入模式:

10000010
01101111
11111110
00001101
10001010
11110101
10000101
00010000
00001001
01001010
00000001
00000000
01010101
00001000
01010111
00000011
10001010
00000010
00100000

输出模式:

10000010
11110110
11111110
10110000
10100010
10101111
10100001
10000000
10010000
10100100
10000000
00000000
10101010
10000000
11101010
11000000
10100010
10000000
10000000

【问题讨论】:

  • [Convert]::ToString($_, 2) -> $($ca=[Convert]::ToString($_, 2).ToCharArray(); [Array]::Reverse($ca); New-Object String (,$ca))
  • 字节到位:$bytes = [byte[]]@(0,1,2,3,4,5); $bits = [Collections.BitArray]$bytes。位到字节:$bytes = [byte[]]::new([Math]::floor(($bits.length-1)/8)+1); $bits.copyTo($bytes,0)。您的问题中有很多代码我未能连接到turning ByteArrays into Bits and then bringing them back 的原始目标。
  • @PetSerAl 反转它不起作用,也省略了填充。
  • @user3661504 我没有省略填充。我只替换[Convert]::ToString($_, 2) 部分。

标签: c# .net powershell powershell-4.0 bitarray


【解决方案1】:

这是另一种使用正则表达式拆分的方法。 在此声明之后:

$List | % {$BitArray[$_ - 1] = $True}

用一和零创建另一个数组(或字符串)

0..($BitArray.Count -1) | % {if ($BitArray[$_]) {$strBitArray += @("1")} else {$strBitArray += @("0")}}

使用正则表达式将字符串分成 8 位块:

$ByteArray = $strBitArray  -join('') -split '(?<=\G[01]{8})(?=.)' | %{[convert]::ToInt64($_,2)}

【讨论】:

    【解决方案2】:

    您的代码目前存在两个问题。

    正如@PetSerAl 所暗示的,BitArray.CopyTo() 似乎颠倒了顺序/字节序。

    这是我个人使用的函数(移植自this C# extension method):

    function ConvertTo-ByteArray {
    
        param([System.Collections.BitArray]$BitArray)
    
        $numBytes = [System.Math]::Ceiling($BitArray.Count / 8)
    
        $bytes = New-Object byte[] $numBytes
        $byteIndex = 0 
        $bitIndex = 0
    
        for ($i = 0; $i -lt $BitArray.Count; $i++) {
            if ($BitArray[$i]){
                $bytes[$byteIndex] = $bytes[$byteIndex] -bor (1 -shl (7 - $bitIndex))
            }
            $bitIndex++
            if ($bitIndex -eq 8) {
                $bitIndex = 0
                $byteIndex++
            }
        }
    
        ,$bytes
    }
    

    您的第二个问题不是转换本身,而是您向byte 字符串添加填充的方式:

    [Convert]::ToString($_, 2).PadRight(8,'0')
    

    PadRight() 会将零添加到字符串的end,而不是开头。

    把它改成PadLeft(),你会得到正确的输出:

    ($result | % { [Convert]::ToString($_, 2).PadLeft(8,'0')})
    

    【讨论】:

    • 如果你只是将PadRight替换为PadLeft,那么结果仍然与将$BitArray转换为字符串的代码不同。
    • @PetSerAl 你说得对,我使用自己的函数将 BitArray 转换为 [byte[]],得到了预期的结果
    • @MathiasR.Jessen 谢谢!使用该代码它可以工作,我可以往返返回 BitArray,如下所示:$SecondBitArray = New-Object BitArray(152); $SecondBitArray = (($result | % { [Convert]::ToString($_, 2).PadLeft(8,'0')}) -join "" -split"(?&lt;=\d)(?=\d)") | % {[bool][int]$_}
    • 恕我直言,这不是BitArray.CopyTo 错误。从$BitArray 转换时,OP 将最低有效(最小索引)位放在首位。但是[Convert]::ToString 将最低有效位放在最后,因为人类是这样写数字的。
    • @PetSerAl 同意,应该更新答案以反映这一点
    猜你喜欢
    • 2013-11-29
    • 1970-01-01
    • 2017-10-02
    • 2018-02-28
    • 2012-09-20
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    • 2012-07-28
    相关资源
    最近更新 更多