I got this code working, which converts from hex to base64, and vice versa. I got to_base64
from another SO question, and I wrote to_hex
with some guesswork and trial and error.
class String
def to_base64
[[self].pack("H*")].pack("m0")
end
def to_hex
self.unpack("m0").first.unpack("H*").first
end
end
But I don't really grok the pack
and unpack
methods, even after reading the docs. Specifically, I'm confused by the asymmetry between the two implementations. Conceptually, in both cases, we take a string encoded in some base (16 or 64), and we wish to convert it to another base. So why can't we implement to_hex
like this:
def to_hex
[[self].pack("m0")].pack("H*")
end
or to_base64
using unpack
? Why does the base we chose completely change the method we need to use to accomplish conversions?
to_hex
is the exact inverse ofto_base64
:to_base64
[self]
H*
:[self].pack("H*")
[[self].pack("H*")]
m0
:[[self].pack("H*")].pack("m0")
to_hex
m0
:self.unpack("m0")
self.unpack("m0").first
H*
:self.unpack("m0").first.unpack("H*")
self.unpack("m0").first.unpack("H*").first
That's how you undo operations, by applying the inverse operations:
And the other way around:
a.pack
is the inverse ofa.unpack
anda.first
is the inverse of[a]