blog

Unpack Ruby Pack

Posted 21.10.2009

Today someone asked me an interesting question: how can I print a string in hexadecimal in ruby?

The solution that immediately jumped into my mind was something like “abc”.map {…}. The first problem here is #map is based on #each, and String#each will iterate on lines instead of characters. So “abc”.map {…} will have only 1 iteration, which give you access to “abc” as a whole inside the iteration.

It’s natural that I then went to String#each_byte for help. “abc”.each_byte {…} will iterate on characters. The problem with each_byte is its return value is the string itself, instead of the result after processing like map. We can’t get a one-line solution with each_byte:

res = []

"abc".each_byte {|i| res << i}

res.map {|i| i.to_s(16)}

3 lines for a simple problem! Ugly, right?

Then I remembered the swissarmy knife of ruby: String#unpack. String#unpack takes a string as directives and applies those directives on its caller. Its caller, a string, is used as a (binary) data stream in this process. For example:

"a".unpack('c') # => [97]

‘c’ is a directive which will extract a character as an integer. You can apply many directives at the same time, like:

"abc".unpack('cH') # => [97, "6"]

which will execute ‘c’ on the first character, and ‘H’ on the second. You can append a number or ‘*’ to a directive so it will be executed many times:

"abc".unpack('c2') # => [97, 98]

"abc".unpack('c*') # => [97, 98, 99]

And String#unpack provides us a directive to extract characters into a hex digit! Here’s the solution using unpack to my friend’s question:

"abc".unpack('H*')

There are many directives you can use in unpack. Whenever you want to transform a string into another common format, like ascii, base64, please give String#unpack a glance, it may resolve your problem instantly.

Name *Please use your real name
Email *Required. Will not be published
Website

That's all for now. This article brought to you by The Plant, makers of Joblet, PiqShare,

and many other fine web apps and content management systems.

Pick up our RSS feed while you are here.