rakaur
rakaur

Reputation: 481

unpack base64-encoded 32bit integer representing IP address

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

Answers (2)

David J.
David J.

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 string
  • pa = plain array
  • pbs = plain binary string
  • es = encoded string

For 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

user149341
user149341

Reputation:

Adding padding (DMmN60==) and decoding gives me the bytes:

0C C9 8D EB

Which decodes to 12.201.141.235.

Upvotes: 2

Related Questions