How can I convert "1234567890"
to "\x12\x34\x56\x78\x90"
in Ruby?
Asked
Active
Viewed 1.9k times
18

Maarten Bodewes
- 90,524
- 13
- 150
- 263
-
Judging by the answers, the output is supposed to be "\x12\x34\x56\x78\x90", rather than an Array of Fixnum or a syntactically invalid Hash. – Martin Dorey Jul 26 '13 at 20:55
6 Answers
34
Try this:
["1234567890"].pack('H*')

patrick
- 838
- 8
- 11
-
This is definitely the most elegant solution. The top voted answer will not do what is asked. – Niklas B. Mar 30 '12 at 13:50
11
Ruby 1.8 -
hex_string.to_a.pack('H*')
Ruby 1.9 / Ruby 1.8 -
Array(hex_string).pack('H*')

Vikrant Chaudhary
- 11,089
- 10
- 53
- 68
-
File.open('output.txt', 'w+') {|f| f.write(IO.read('input.txt').to_a.pack('H*')) } – neoneye Jun 24 '10 at 14:47
-
I'm not sure how your answer is supposed to work. Could you give a better example using the hex string in the question? When I tried your code I got: `d:\>irb irb(main):001:0> hex_string = "1234567890" => "1234567890" irb(main):002:0> hex_string.to_a.pack('H*') NoMethodError: undefined method `to_a' for "1234567890":String from (irb):2 from C:/Ruby192/bin/irb:12:in `
' irb(main):003:0>` – ZombieDev Oct 05 '11 at 17:12 -
@ZombieDev, @steenslag Ruby 1.9 doesn't have `String#to_a` method. I've updated my answer to reflect that. – Vikrant Chaudhary May 04 '12 at 05:47
8
Assuming you have a well-formed hexadecimal string (pairs of hex digits), you can pack to binary, or unpack to hex, simply & efficiently, like this:
string = '0123456789ABCDEF'
binary = [string].pack('H*') # case-insensitive
=> "\x01#Eg\x89\xAB\xCD\xEF"
hex = binary.unpack('H*').first # emits lowercase
=> "012345679abcdef"

Trashpanda
- 14,758
- 3
- 29
- 18
4
class String
def hex2bin
s = self
raise "Not a valid hex string" unless(s =~ /^[\da-fA-F]+$/)
s = '0' + s if((s.length & 1) != 0)
s.scan(/../).map{ |b| b.to_i(16) }.pack('C*')
end
def bin2hex
self.unpack('C*').map{ |b| "%02X" % b }.join('')
end
end

McDowell
- 107,573
- 31
- 204
- 267

Randy Langer
- 49
- 1
1
If you have a string containing numbers and you want to scan each as a numeric hex byte, I think this is what you want:
"1234567890".scan(/\d\d/).map {|num| Integer("0x#{num}")}

Chuck
- 234,037
- 30
- 302
- 389
-
-
1Or, to handle **hex** characters as requested, `"1234567890abcdef".scan(/[0-9A-Fa-f]{2}/).map { |i| i.to_i(16) }`. – Huw Walters Apr 14 '11 at 10:55
-1
(0..4).map { |x| "0x%X" % (("1234567890".to_i(16) >> 8 * x) & 255) }.reverse

McDowell
- 107,573
- 31
- 204
- 267

Kevin Peterson
- 7,189
- 5
- 36
- 43