I needed a method of converting a text representation of a binary file (eg. the text 'AE00F00D' in a file) to the binary byte equivalent and vice versa.
Included are the PowerShell scripts I ended up writing for the task. The core parts of script are below, click 'Read More!' to see the full .PS1 scripts
Note that I have updated the original post, as the '-readcount 0' when reading the file, pre-allocating the array (thanks for the suggestion Phil) and using an assigned variable in the for loop made this much faster.
[byte[]]$bytes = Get-Content -encoding byte -readcount 0 -path $BinaryFile
for ($i = 0; $i -le $count-1; $i++)
{ $hex = "{0:x}" -f $bytes[$i]
[void]$output.Append($hex.PadLeft(2, "0")) # Pad any single digits
}
set-content $OutputFile -value $output.ToString()
$HexString = Get-Content -readcount 0 -path $HexStringFile
for ( $i = 0; $i -le $count-1; $i+=2 )
{ $bytes[$x] = [byte]::Parse($hexString.Substring($i,2), [System.Globalization.NumberStyles]::HexNumber)
$x += 1 }
set-content -encoding byte $OutputFile -value $bytes
I was using this to restore and update some images stored in
#HexStringToBinary.ps1
param(
[string] $HexStringfile = "",
[string] $OutputFile = ""
)
if ($HexstringFile -ne "") {
$HexString = Get-Content -readcount 0 -path $HexStringFile
$HexString = $HexString[0]
$count = $hexString.length
$byteCount = $count/2
$bytes = New-Object byte[] $byteCount
$byte = $null
$x = 0
for ( $i = 0; $i -le $count-1; $i+=2 )
{
$bytes[$x] = [byte]::Parse($hexString.Substring($i,2), [System.Globalization.NumberStyles]::HexNumber)
$x += 1
}
if ($OutputFile -ne "") {
set-content -encoding byte $OutputFile -value $bytes
} else {
write-host "No output file specified"
}
} else{
write-host "Error, no input file specified"
}
# Byte.Parse Method (String, NumberStyles)
# http://msdn.microsoft.com/en-us/library/4eszwye3(VS.80).aspx
#BinaryToHexString.ps1
param(
[string] $Binaryfile = "",
[string] $OutputFile = ""
)
if ($BinaryFile -ne "") {
[byte[]]$bytes = Get-Content -encoding byte -readcount 0 -path $BinaryFile # Use a readCount of 0 to read all lines at once
$output = new-object System.Text.StringBuilder # Using stringBuilder seems faster than $a = $a + "a" ?
$count = $bytes.length # The loop seems much faster when using a pre-set value?
for ($i = 0; $i -le $count-1; $i++)
{
$hex = "{0:x}" -f $bytes[$i]
[void]$output.Append($hex.PadLeft(2, "0")) # Pad any single digits
}
if ($OutputFile -ne "") {
set-content $OutputFile -value $output.ToString()
} else {
write-host "No output file specified"
}
} else{
write-host "Error, no input file specified"
}
# .net formatting decimal to hex
# http://www.microsoft.com/technet/scriptcenter/topics/winpsh/convert/hex.mspx
Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.
Information regarding Windows Infrastructure, centred mostly around commandline automation and other useful bits of information.
2 comments:
Clever. It would be interesting to benchmark the text to binary conversion to see how well powershell can optimize things. The "[byte[]]$bytes = $bytes + $byte" part would just do hexString.length/2 memory allocations in C#, so I wonder if PowerShell is a bit cleverer on it's optimisations.
If not, would it be possible to preallocate the array, perhaps New-Object byte[] hexString.length/2 ? I wonder if it would even matter.
Thank you for the scripts!
Post a Comment