Powershell 中的位掩码转换
Bitmask conversion in Powershell
我正在使用代表错误代码的位掩码。例如,值 3(二进制 11)表示遇到了错误 1 和 2(二进制 1 和 10)。我正在寻找一个在 powershell 中自动将其转换为数组的函数。
我在 Internet 上四处寻找,找不到任何与此场景相关的内容。我已经编写了一个执行此操作的函数,但如果用户不熟悉位掩码,它的可读性就不太好。
EDIT 具体来说,我正在寻找一个接受 'raw' 错误位并将其用于 return 错误数组的函数。例如:
GetErrorList 3779
returns 数组包含:
1, 2, 64, 128, 512, 1024, 2048
为每个位设置一个包含翻译的哈希表,并使用二进制 AND
运算符 (-band
) 找出引发的错误:
function Get-ErrorDescription {
param([int]$ErrorBits)
$ErrorTable = @{
0x01 = "Error1"
0x02 = "Error2"
0x04 = "Error3"
0x08 = "Error4"
0x10 = "Error5"
0x20 = "Error6"
}
foreach($ErrorCode in $ErrorTable.Keys | Sort-Object){
if($ErrorBits -band $ErrorCode){
$ErrorTable[$ErrorCode]
}
}
}
returns 发现错误的字符串数组,或 $null
PS C:\> Get-ErrorDescription -ErrorBits 3
Error1
Error2
编辑:我在 Powershell 5 中找到了一种使用枚举标志执行此操作的非常酷的方法:
[flags()] Enum ErrorTable
{
Error1 = 0x01
Error2 = 0x02
Error3 = 0x04
Error4 = 0x08
Error5 = 0x10
Error6 = 0x20
}
PS C:\> $errorcodes = [ErrorTable]'Error1,Error2'
PS C:\> $errorcodes
Error1, Error2
PS C:\> $errorcodes = [ErrorTable]3
PS C:\> $errorcodes
Error1, Error2
我最近遇到了一个与 OP 非常相似的问题。这个问题有点老了,但这可能对其他人有帮助。
正如 js2010 提到的,你可以使用一个 enumeration defined as a collection of bit flags 来达到很好的效果:
[flags()] Enum ErrorTable {
Error1 = 1
Error2 = 2
Error3 = 4
Error4 = 8
Error5 = 16
Error6 = 32
Error7 = 64
Error8 = 128
Error9 = 256
Error10 = 512
Error11 = 1024
Error12 = 2048
}
function GetErrorList ([int]$ValueIn) {
[ErrorTable]$ValueIn
}
这里GetErrorList其实是返回一串错误,如果你更想要一个数组,那么把函数中的单行改成:
[ErrorTable]$ValueIn -split ', '
这实际上并没有回答 OP 提出的确切问题,但可以在没有枚举的情况下回答如下(当然还有更有效和优雅的方法):
function GetErrorListNumeric ([int]$ValueIn) {
$s = [System.Convert]::ToString($ValueIn,2)
$values = @()
while ($s.length -ge 1) {
if ($s[0] -eq '1') { $values += [Math]::Pow(2,$s.length-1) }
$s = $s -replace '^.', ''
}
[array]::Reverse($values)
$values
}
在我的例子中,我需要将位标志转换为更长的消息字符串。这不适用于枚举,但枚举的值可以使用散列进行转换,如下所示:
$ErrorMessages = @{
Error1 = 'error #1'
Error2 = 'error #2'
Error3 = 'error #4'
Error4 = 'error #8'
Error5 = 'error #16'
Error6 = 'error #32'
Error7 = 'error #64'
Error8 = 'error #128'
Error9 = 'error #256'
Error10 = 'error #512'
Error11 = 'error #1024'
Error12 = 'error #2048'
}
然后,此函数会将原始位掩码转换为组件错误消息:
function GetErrorList ([int]$ValueIn) {
$ErrorMessages[([ErrorTable]$ValueIn -split ', ')]
}
我正在使用代表错误代码的位掩码。例如,值 3(二进制 11)表示遇到了错误 1 和 2(二进制 1 和 10)。我正在寻找一个在 powershell 中自动将其转换为数组的函数。
我在 Internet 上四处寻找,找不到任何与此场景相关的内容。我已经编写了一个执行此操作的函数,但如果用户不熟悉位掩码,它的可读性就不太好。
EDIT 具体来说,我正在寻找一个接受 'raw' 错误位并将其用于 return 错误数组的函数。例如:
GetErrorList 3779
returns 数组包含:
1, 2, 64, 128, 512, 1024, 2048
为每个位设置一个包含翻译的哈希表,并使用二进制 AND
运算符 (-band
) 找出引发的错误:
function Get-ErrorDescription {
param([int]$ErrorBits)
$ErrorTable = @{
0x01 = "Error1"
0x02 = "Error2"
0x04 = "Error3"
0x08 = "Error4"
0x10 = "Error5"
0x20 = "Error6"
}
foreach($ErrorCode in $ErrorTable.Keys | Sort-Object){
if($ErrorBits -band $ErrorCode){
$ErrorTable[$ErrorCode]
}
}
}
returns 发现错误的字符串数组,或 $null
PS C:\> Get-ErrorDescription -ErrorBits 3
Error1
Error2
编辑:我在 Powershell 5 中找到了一种使用枚举标志执行此操作的非常酷的方法:
[flags()] Enum ErrorTable
{
Error1 = 0x01
Error2 = 0x02
Error3 = 0x04
Error4 = 0x08
Error5 = 0x10
Error6 = 0x20
}
PS C:\> $errorcodes = [ErrorTable]'Error1,Error2'
PS C:\> $errorcodes
Error1, Error2
PS C:\> $errorcodes = [ErrorTable]3
PS C:\> $errorcodes
Error1, Error2
我最近遇到了一个与 OP 非常相似的问题。这个问题有点老了,但这可能对其他人有帮助。
正如 js2010 提到的,你可以使用一个 enumeration defined as a collection of bit flags 来达到很好的效果:
[flags()] Enum ErrorTable {
Error1 = 1
Error2 = 2
Error3 = 4
Error4 = 8
Error5 = 16
Error6 = 32
Error7 = 64
Error8 = 128
Error9 = 256
Error10 = 512
Error11 = 1024
Error12 = 2048
}
function GetErrorList ([int]$ValueIn) {
[ErrorTable]$ValueIn
}
这里GetErrorList其实是返回一串错误,如果你更想要一个数组,那么把函数中的单行改成:
[ErrorTable]$ValueIn -split ', '
这实际上并没有回答 OP 提出的确切问题,但可以在没有枚举的情况下回答如下(当然还有更有效和优雅的方法):
function GetErrorListNumeric ([int]$ValueIn) {
$s = [System.Convert]::ToString($ValueIn,2)
$values = @()
while ($s.length -ge 1) {
if ($s[0] -eq '1') { $values += [Math]::Pow(2,$s.length-1) }
$s = $s -replace '^.', ''
}
[array]::Reverse($values)
$values
}
在我的例子中,我需要将位标志转换为更长的消息字符串。这不适用于枚举,但枚举的值可以使用散列进行转换,如下所示:
$ErrorMessages = @{
Error1 = 'error #1'
Error2 = 'error #2'
Error3 = 'error #4'
Error4 = 'error #8'
Error5 = 'error #16'
Error6 = 'error #32'
Error7 = 'error #64'
Error8 = 'error #128'
Error9 = 'error #256'
Error10 = 'error #512'
Error11 = 'error #1024'
Error12 = 'error #2048'
}
然后,此函数会将原始位掩码转换为组件错误消息:
function GetErrorList ([int]$ValueIn) {
$ErrorMessages[([ErrorTable]$ValueIn -split ', ')]
}