Skip to content

Instantly share code, notes, and snippets.

@felixge
Last active August 21, 2018 10:37
Show Gist options
  • Save felixge/7be54ead9cfe166deaf99e1c8a215be0 to your computer and use it in GitHub Desktop.
Save felixge/7be54ead9cfe166deaf99e1c8a215be0 to your computer and use it in GitHub Desktop.
encoded_in = "\x00\x00\x00\x03aaa\x00\x00\x00\x06Binary\x02\x00\x00\x00\fP\x00\x84A\xEB\xF9~?\x966\xE7\x8A\x00\x00\x00\x03ccc\x00\x00\x00\x06String\x01\x00\x00\x00\x04test\x00\x00\x00\x03zzz\x00\x00\x00\x06Number\x01\x00\x00\x00\a0230.01\x00\x00\x00\x10\xC3\xB6ther_encodings\x00\x00\x00\x06String\x01\x00\x00\x00\x05T\xC3\xBCst"
class EncodedMessage
attr_accessor :data
attr_accessor :md5
def initialize(data, md5)
@data = [data].pack('a*')
@md5 = md5
# TODO(fg) verify md5
end
def decode
attributes = []
decoder = Decoder.new(@data)
while !decoder.empty do
attribute = Attribute.new
attribute.decode(decoder)
attributes << attribute
end
return DecodedMessage.new(attributes)
end
end
class DecodedMessage
attr_accessor :attributes
def initialize(attributes)
@attributes = attributes
end
def encode()
encoder = Encoder.new
@attributes.each do |attribute|
attribute.encode(encoder)
end
# TODO calculate md5
md5 = "123"
return EncodedMessag.new(encoder.data, md5)
end
end
class Attribute
attr_accessor :name
attr_accessor :type
attr_accessor :value_type
attr_accessor :value
def decode(decoder)
@name = decoder.var_string
@type = decoder.var_string
@value_type = decoder.num_8
@value = decoder.var_string
end
def encode(encoder)
encoder.var_string(@name)
encoder.var_string(@type)
encoder.num_8(@value_type)
encoder.var_string(@value)
end
end
class Decoder
attr_accessor :data
def initialize(data)
@data = data
end
def var_string()
l = @data.unpack('L>')[0]
@data = @data.byteslice(4..-1)
s = @data.unpack('a'+String(l))[0]
@data = @data.byteslice(l..-1)
return s
end
def num_8()
n = @data.unpack('C')[0]
@data = @data.byteslice(1..-1)
return n
end
def empty()
return @data.bytesize == 0
end
end
class Encoder
attr_accessor :data
def initialize()
@data = ""
end
def var_string(s)
@data += [s.bytesize].pack('L>*')
@data += [s].pack('a*')
end
def num_8(n)
@data += [n].pack('C')
end
end
def hex(s)
s.each_byte.map { |b| b.to_s(16) }.join(' ')
end
em = EncodedMessage.new(encoded_in, "abc")
p(em.data)
p(em)
dm = em.decode()
p(dm)
encoded_out = dm.encode()
p(encoded_out)
p(em.data == encoded_out)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment