如何在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
)
如果确实希望将数据存储为typeREG_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)})