将字节数组(十六进制)转换为带符号的 Int
Convert byte array (hex) to signed Int
我正在尝试将(可变长度)十六进制字符串转换为有符号整数(我需要正值或负值)。
[Int16] [int 32] 和 [int64] 似乎 可以很好地处理 2,4+ 字节长度的十六进制字符串,但我坚持使用 3 字节字符串 [int24 ](在 powershell 中没有这样的命令)。
这是我现在拥有的(片段):
$start = $mftdatarnbh.Substring($DataRunStringsOffset+$LengthBytes*2+2,$StartBytes*2) -split "(..)"
[array]::reverse($start)
$start = -join $start
if($StartBytes*8 -le 16){$startd =[int16]"0x$($start)"}
elseif($StartBytes*8 -in (17..48)){$startd =[int32]"0x$($start)"}
else{$startd =[int64]"0x$($start)"}
使用上面的代码,"D35A71" 的 $start 值给出“13851249”而不是“-2925967”。我试图找出一种实现二进制补码的方法,但迷路了。有什么简单的方法可以做到这一点吗?
提前致谢
编辑:基本上,我想我需要实现这样的东西:
int num = (sbyte)array[0] << 16 | array[1] << 8 | array[2];
如所见 here.
刚试过这个:
$start = "D35A71"<br>
[sbyte]"0x$($start.Substring(0,2))" -shl 16 -bor "0x$($start.Substring(2,2))" -shl 8 -bor "0x$ ($start.Substring(4,2))"
但似乎没有得到正确的结果:-/
要将您的十六进制数字字符串解析为 负数 数字,您可以使用[bigint]
(System.Numerics.BigInteger
):
# Since the most significant hex digit has a 1 as its most significant bit
# (is >= 0x8), it is parsed as a NEGATIVE number.
# To force unconditional interpretation as a positive number, prepend '0'
# to the input hex string.
PS> [bigint]::Parse('D35A71', 'AllowHexSpecifier')
-2925967
您可以将生成的 [bigint]
实例转换回 [int]
(System.Int32
)。
注:
结果是一个负数,因为最重要的十六进制数字十六进制输入字符串是 >= 0x8
,即设置了 高位 .
- 强制
[bigint]
无条件解释一个十六进制。输入字符串作为 positive 数字,prepend 0
.
生成的负数数字的内部two's complement表示在字节[=76处执行=] boundaries,因此给定的十六进制数具有 odd 个数字(即,如果第一个十六进制数字是 "half byte")有缺失的一半用 1
位填充的字节。
- 因此,最高有效位为
>= 0x8
的十六进制数字字符串(解析为 负数 数字)导致 与一个或多个 F
s (0xF
== 1111
) 相同 ];例如,以下调用 all 导致 -2048
:
[bigint]::Parse('800', 'AllowHexSpecifier')
,
[bigint]::Parse('F800', 'AllowHexSpecifier')
,
[bigint]::Parse('FF800', 'AllowHexSpecifier'
), ...
有关解析逻辑的详细信息,请参阅 the docs。
示例:
# First digit (7) is < 8 (high bit NOT set) -> positive number
[bigint]::Parse('7FF', 'AllowHexSpecifier') # -> 2047
# First digit (8) is >= 8 (high bit IS SET) -> negative number
[bigint]::Parse('800', 'AllowHexSpecifier') # -> -2048
# Prepending additional 'F's to a number that parses as
# a negative number yields the *same* result
[bigint]::Parse('F800', 'AllowHexSpecifier') # -> -2048
[bigint]::Parse('FF800', 'AllowHexSpecifier') # -> -2048
# ...
# Starting the hex-number string with '0'
# *unconditionally* makes the result a *positive* number
[bigint]::Parse('0800', 'AllowHexSpecifier') # -> 2048
我正在尝试将(可变长度)十六进制字符串转换为有符号整数(我需要正值或负值)。
[Int16] [int 32] 和 [int64] 似乎 可以很好地处理 2,4+ 字节长度的十六进制字符串,但我坚持使用 3 字节字符串 [int24 ](在 powershell 中没有这样的命令)。
这是我现在拥有的(片段):
$start = $mftdatarnbh.Substring($DataRunStringsOffset+$LengthBytes*2+2,$StartBytes*2) -split "(..)"
[array]::reverse($start)
$start = -join $start
if($StartBytes*8 -le 16){$startd =[int16]"0x$($start)"}
elseif($StartBytes*8 -in (17..48)){$startd =[int32]"0x$($start)"}
else{$startd =[int64]"0x$($start)"}
使用上面的代码,"D35A71" 的 $start 值给出“13851249”而不是“-2925967”。我试图找出一种实现二进制补码的方法,但迷路了。有什么简单的方法可以做到这一点吗?
提前致谢
编辑:基本上,我想我需要实现这样的东西:
int num = (sbyte)array[0] << 16 | array[1] << 8 | array[2];
如所见 here.
刚试过这个:
$start = "D35A71"<br>
[sbyte]"0x$($start.Substring(0,2))" -shl 16 -bor "0x$($start.Substring(2,2))" -shl 8 -bor "0x$ ($start.Substring(4,2))"
但似乎没有得到正确的结果:-/
要将您的十六进制数字字符串解析为 负数 数字,您可以使用[bigint]
(System.Numerics.BigInteger
):
# Since the most significant hex digit has a 1 as its most significant bit
# (is >= 0x8), it is parsed as a NEGATIVE number.
# To force unconditional interpretation as a positive number, prepend '0'
# to the input hex string.
PS> [bigint]::Parse('D35A71', 'AllowHexSpecifier')
-2925967
您可以将生成的 [bigint]
实例转换回 [int]
(System.Int32
)。
注:
结果是一个负数,因为最重要的十六进制数字十六进制输入字符串是
>= 0x8
,即设置了 高位 .- 强制
[bigint]
无条件解释一个十六进制。输入字符串作为 positive 数字,prepend0
.
- 强制
生成的负数数字的内部two's complement表示在字节[=76处执行=] boundaries,因此给定的十六进制数具有 odd 个数字(即,如果第一个十六进制数字是 "half byte")有缺失的一半用
1
位填充的字节。- 因此,最高有效位为
>= 0x8
的十六进制数字字符串(解析为 负数 数字)导致 与一个或多个F
s (0xF
==1111
) 相同 ];例如,以下调用 all 导致-2048
:
[bigint]::Parse('800', 'AllowHexSpecifier')
,
[bigint]::Parse('F800', 'AllowHexSpecifier')
,
[bigint]::Parse('FF800', 'AllowHexSpecifier'
), ...
- 因此,最高有效位为
有关解析逻辑的详细信息,请参阅 the docs。
示例:
# First digit (7) is < 8 (high bit NOT set) -> positive number
[bigint]::Parse('7FF', 'AllowHexSpecifier') # -> 2047
# First digit (8) is >= 8 (high bit IS SET) -> negative number
[bigint]::Parse('800', 'AllowHexSpecifier') # -> -2048
# Prepending additional 'F's to a number that parses as
# a negative number yields the *same* result
[bigint]::Parse('F800', 'AllowHexSpecifier') # -> -2048
[bigint]::Parse('FF800', 'AllowHexSpecifier') # -> -2048
# ...
# Starting the hex-number string with '0'
# *unconditionally* makes the result a *positive* number
[bigint]::Parse('0800', 'AllowHexSpecifier') # -> 2048