Reputation: 481
I have a base64-encoded, 32-bit integer, that's an IP address: DMmN60
I cannot for the life of me figure out how to both unpack it and turn it into a quad-dotted representation I can actually use.
Unpacking it with unpack('m') actually only gives me three bytes. I don't see how that's right either, but this is far from my expertise.
Upvotes: 2
Views: 1991
Reputation: 32705
Hello from the future (two years later) with Ruby 1.9.3. To encode:
require 'base64'
ps = "204.152.222.180"
pa = ps.split('.').map { |_| _.to_i } # => [204, 152, 222, 180]
pbs = pa.pack("C*") # => "\xCC\x98\xDE\xB4"
es = Base64.encode64(s) # => "zJjetA==\n"
To decode:
require 'base64'
es = "zJjetA==\n"
pbs = Base64.decode64(es) # => "\xCC\x98\xDE\xB4"
pa = pbs.unpack("C*") # => [204, 152, 222, 180]
ps = pa.map { |_| _.to_s }.join('.') # => "204.152.222.180"
Name explanation:
ps
= plain stringpa
= plain arraypbs
= plain binary stringes
= encoded stringFor your example:
Base64.decode64("DMmN60==").unpack("C*").map { |_| _.to_s }.join('.')
# => "12.201.141.235"
Just like @duskwuff said.
Your comment above said that the P10 base64 is non-standard, so I took a look at: http://carlo17.home.xs4all.nl/irc/P10.html which defines:
<base64> = 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','[',']'
It is the same as http://en.wikipedia.org/wiki/Base64 -- except that the last two characters are +
and /
in the normal Base64. I don't see how this explains the discrepancy, since your example did not use those characters. I do wonder, however, if it was due to some other factor -- perhaps an endian issue.
Upvotes: 3
Reputation:
Adding padding (DMmN60==
) and decoding gives me the bytes:
0C C9 8D EB
Which decodes to 12.201.141.235.
Upvotes: 2