class HrrRbSsh::DataType::Mpint
Mpint
provides methods to convert integer value and multiple precision integer in two's complement as binary string each other.
Public Class Methods
decode(io)
click to toggle source
Convert multiple precision integer in two's complement as binary string into integer value.
@param [::IO] io IO instance that has buffer to be read @return [::Integer] converted integer value
# File lib/hrr_rb_ssh/data_type/mpint.rb, line 40 def self.decode io length = io.read(4).unpack("N")[0] hex_str = io.read(length).unpack("H*")[0] # get temporal integer value value = hex_str.hex if length == 0 0 elsif value[(length * 8) - 1] == 0 value else num_bytes = if hex_str.start_with?("ff") then length - 1 else length end - (((~ value) & ((1 << (num_bytes * 8)) - 1)) + 1) end end
encode(arg)
click to toggle source
Convert integer value into multiple precision integer in two's complement as binary string.
@param [::Integer] arg integer value to be converted @raise [::ArgumentError] when arg is not an integer value @return [::String] converted multiple precision integer in two's complement as binary string
# File lib/hrr_rb_ssh/data_type/mpint.rb, line 15 def self.encode arg unless arg.kind_of? ::Integer raise ArgumentError, "must be a kind of Integer, but got #{arg.inspect}" end bn = ::OpenSSL::BN.new(arg) if bn < 0 # get 2's complement tc = bn.to_i & ((1 << (bn.num_bytes * 8)) - 1) # get hex representation hex_str = "%x" % tc if tc[(bn.num_bytes * 8) - 1] == 1 [bn.num_bytes, hex_str].pack("NH*") else [bn.num_bytes + 1, "ff" + hex_str].pack("NH*") end else bn.to_s(0) end end