If only I were

Building Great Software

PowerShell Hex to Char

with 4 comments

Rob Conery posted a poem in hex on Friday and since I’m playing with PowerShell quite a bit, I decided to convert it back to readable English with some PowerShell.

First, I copied and pasted the hex characters into a text file and saved it as message.txt.

Next, I needed to load the file into a PowerShell variable so I could manipulate it. I’m issued the command in the same directory where message.txt is located.

$m = gc message.txt

Explanation: PowerShell variables are always prefixed with a $ symbol so in this case $m is going to hold the contents of message.txt.  gc is an alias to the Get-Content cmdlet which literally get the contents of a file.

Next, we build up the actual statement to convert the hex values to decimal and then decimal values to a characters.

$m.Split() | % {[Convert]::ToInt32($_,16)} | %{[Convert]::ToChar($_)}

.Net Type Explanation: $m is a string type at this point. You can verify it by issuing this statement – $m.GetType().FullName – and you will get System.String back. PowerShell is built on top of the .Net type system so you have access to all of the same objects and members as you do in C# or VB.Net.  $m.Split() is going to give back an array of strings.

Pipeline Explanation: You can’t go very far in PowerShell without encountering the pipeline. The statement above you read from left to right, and you use the | symbol to separate the statement into three distinct sections. The first section makes an array of strings from the original data.  The second section converts each hex value to an integer and the third section changes the decimal value to a readable character.  Each section of the pipeline gets processed and then the results of the current section get passed to the section to its right so it can do a new set of operations.

% Explanation: The % symbol is an alias to the ForEach-Object cmdlet. It is also aliased as foreach. % is usually going to be paired with a block {} that will be repeated for each item in a list/collection/array.

$_ Explanation: $_ is a variable reference to the current item in the foreach operation.

[Convert] Explanation: Square brackets around a word like [Convert] say that you are invoking a preexisting .Net type called Convert. If you were writing a C# or VB.Net app you could easily call Convert.ToInt32(“32”) and it would convert the string representation to an integer type.  So here, [Convert].ToInt32($_, 16) is an overload of the ToInt32 function that takes a string representation of a hex value and converts it to an integer.

:: Explanation: The :: operator lets you invoke a method or property on a .Net Type, hence we have [Convert]::ToInt32($_,16)

You have to read this poem vertically at this point, but you can do the work to fix that. I’m almost sure there are probably some ways to simplify this expression as well, so feel free to post comments on improvements you would make. This has become a much longer post than I originally intended, but before I sign off here is what the fully qualified expression would look like:

$m.Split() | ForEach-Object {[Convert]::ToInt32($_,16)} | ForEach-Object {[Convert]::ToChar($_)}

Advertisements

Written by Chris Sutton

March 30, 2008 at 2:36 pm

Posted in Technology

Tagged with , , , ,

4 Responses

Subscribe to comments with RSS.

  1. Hi

    You can convert to char in the first foreach:

    $m.split() | % {[Char][Convert]::ToInt32($_,16)}

    PowerShell is so COOL!

    —–
    Shay Levy
    $cript Fanatic
    http://scriptolog.blogspot.com

    Shay

    March 31, 2008 at 1:15 am

  2. Pipe it to Write-Host $_ -NoNewLine to read it horizontally. Turns out the linebreaks are also included, so this returns it in proper formatting.

    Hugo
    http://www.peetersonline.nl

    hugopeeters

    January 19, 2009 at 4:48 am

  3. $m.Split() | ForEach-Object {[Convert]::ToInt32($_,16)} | ForEach-Object {[Convert]::ToChar($_)} | ForEach-Object{Write-Host $_ -NoNewLine} ; Write-Host

    This works perfectly. That extra Write-Host at the end is to add a newline before your prompt comes back. Neat stuff. ^_^

    andrew

    May 27, 2010 at 7:45 am

    • No need to use write-host to fix the formatting; the -join operator will concatenate the letters for you
      -join ($m.split() | %{[Char][Convert]::ToInt32($_,16)})

      Owen

      October 31, 2011 at 12:17 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: