Class: HrrRbSsh::DataType::Mpint
- Inherits:
-
HrrRbSsh::DataType
- Object
- HrrRbSsh::DataType
- HrrRbSsh::DataType::Mpint
- Defined in:
- lib/hrr_rb_ssh/data_type/mpint.rb
Overview
Mpint provides methods to convert integer value and multiple precision integer in two’s complement as binary string each other.
Class Method Summary collapse
-
.decode(io) ⇒ ::Integer
Convert multiple precision integer in two’s complement as binary string into integer value.
-
.encode(arg) ⇒ ::String
Convert integer value into multiple precision integer in two’s complement as binary string.
Class Method Details
.decode(io) ⇒ ::Integer
Convert multiple precision integer in two’s complement as binary string into integer value.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# 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) ⇒ ::String
Convert integer value into multiple precision integer in two’s complement as binary string.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# 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 |