如何在PowerShell中将哈希字符串转换为字节数组?

如何在PowerShell中将哈希字符串转换为字节数组?,powershell,registry,Powershell,Registry,当我的脚本运行时,我读取一个散列,我想将它写入注册表。 我发现下面的命令可以做到这一点: New-ItemProperty $RegPath -Name $AttrName -PropertyType Binary -Value $byteArray 我还找到了 但是,所有答案都假设字符串的形式为: "50,33,01,00,00,00,00,00,...." 但我只能读取以下格式的哈希: "F5442930B1778ED31A....." 我不知道如何将其转换为值为F5、44等的字节数

当我的脚本运行时,我读取一个散列,我想将它写入注册表。 我发现下面的命令可以做到这一点:

New-ItemProperty  $RegPath -Name $AttrName -PropertyType Binary -Value $byteArray
我还找到了

但是,所有答案都假设字符串的形式为:

"50,33,01,00,00,00,00,00,...."
但我只能读取以下格式的哈希:

"F5442930B1778ED31A....."
我不知道如何将其转换为值为F5、44等的字节数组。

明智地建议将散列直接存储为注册表中的字符串(
REG_SZ

如果确实希望将数据存储为type
REG_BINARY
,即作为字节数组,则必须在字符串表示形式之间来回转换

转换为
[字节[]]
数组
(使用缩短的样本哈希字符串):

以上是PowerShell对结果数组的默认输出表示形式
[字节[]](0xf5、0x44、0x29)


要从
[字节[]]
数组转换为(返回到字符串;PSv4+语法):

.ForEach('ToString','X2')
相当于调用
.ToString('X2')
——也就是说,在每个数组元素上请求一个填充为2位的十六进制表示形式,并收集结果字符串
-join
然后通过直接连接将这些字符串连接到单个字符串


总而言之:

# Sample hash string.
$hashString = 'F54429'

# Convert the hash string to a byte array.
$hashByteArray = [byte[]] ($hashString -replace '..', '0x$&,' -split ',' -ne '')

# Create a REG_BINARY registry value from the byte array.
Set-ItemProperty -LiteralPath HKCU:\ -Name tmp -Type Binary -Value $hashByteArray

# Read the byte array back from the registry (PSv5+)
$hashByteArray2 = Get-ItemPropertyValue -LiteralPath HKCU:\ -Name tmp

# Convert it back to a string.
$hashString2 = -join $hashByteArray2.ForEach('ToString', 'X2')

# (Clean up.)
Remove-ItemProperty -LiteralPath HKCU:\ -Name tmp

要在不使用正则表达式权重的情况下解析十六进制字符串,请执行以下操作:

# parse the hex string into a BigInt
# leading zeros avoids parsing as negative
$bytes = [bigint]::Parse("00$value",'HexNumber').ToByteArray()

# undo the reversed bytes
[array]::Reverse($bytes)

# drop the leading zero byte
$null,$bytes = $bytes

下面是另一种不使用正则表达式的方法

function HexToByteArray([string]$hex) {
(0..([Math]::Floor( ($hex.Length+1)/2)-1)).ForEach({[Convert]::ToByte($(if ($hex.Length -ge 2*($_+1)) {$hex.Substring($_*2,2)} else {$hex.Substring($_*2,1).PadRight(2,'0')}),16)})
}


它可能比您想要的更健壮—它尝试支持奇数长度的输入字符串。您可能更喜欢不允许奇数长度的输入字符串,在这种情况下,转换表达式可以简化。

散列应该是二进制对象吗?我以为它们应该是十六进制数或字符串…为什么不使用reg_sz并将其存储为字符串?也就是说,SANS大约有字节和十六进制。@vonPryz这是一个MS设置,很遗憾,格式不由我决定。
# parse the hex string into a BigInt
# leading zeros avoids parsing as negative
$bytes = [bigint]::Parse("00$value",'HexNumber').ToByteArray()

# undo the reversed bytes
[array]::Reverse($bytes)

# drop the leading zero byte
$null,$bytes = $bytes
function HexToByteArray([string]$hex) {
(0..([Math]::Floor( ($hex.Length+1)/2)-1)).ForEach({[Convert]::ToByte($(if ($hex.Length -ge 2*($_+1)) {$hex.Substring($_*2,2)} else {$hex.Substring($_*2,1).PadRight(2,'0')}),16)})