Class: IpAddress
Constant Summary collapse
- IP_BITS =
{4 => 32, 6 => 128}
- IP_MAX =
{4 => (1 << 32) - 1, 6 => (1 << 128) - 1}
Instance Attribute Summary collapse
-
#integer ⇒ Object
readonly
Returns the value of attribute integer.
-
#string ⇒ Object
readonly
Returns the value of attribute string.
-
#version ⇒ Object
readonly
Returns the value of attribute version.
Class Method Summary collapse
-
.coerce(value, to_type, version = nil) ⇒ Object
Takes an Integer or a String representation of an IP address and coerces it to a representation of the requested type (:integer / :string).
-
.guess_version(value) ⇒ Object
Takes an Integer or a String and guesses whether it represents an IPv4 or IPv6 address.
-
.mask_from_slash_bits(bits, version = nil) ⇒ Object
Takes an Integer bitcount (bits) and returns an appropriate masking Integer.
-
.mask_size(value, version = nil) ⇒ Object
Takes an Integer or a String representation of a network mask and returns the number of addresses it encodes.
Instance Method Summary collapse
-
#+(value) ⇒ Object
Adds the specified Integer value to that of the IpAddress and returns a new IpAddress based on the sum.
-
#-(value) ⇒ Object
Subtracts the specified Integer value from that of the IpAddress and returns a new IpAddress based on the difference.
-
#/(bits) ⇒ Object
Returns the range of IpAddresses in the specified /bits network.
-
#<=>(other) ⇒ Object
Compares one IpAddress with another based on the Integer representation of their values.
-
#initialize(value, version = nil) ⇒ IpAddress
constructor
Takes an Integer or a String representation of an IP address and creates a new IpAddress object with it.
-
#mask(value) ⇒ Object
Takes an Integer or a String representation of a network mask and returns the range of IpAddresses in that network.
-
#succ ⇒ Object
Returns the next IpAddress after this one.
- #to_i ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(value, version = nil) ⇒ IpAddress
Takes an Integer or a String representation of an IP address and creates a new IpAddress object with it. If the version (4 / 6) is not specified then it will be guessed with guess_version.
62 63 64 65 66 |
# File 'lib/ip_address.rb', line 62 def initialize(value, version = nil) @version = version || IpAddress.guess_version(value) @integer = IpAddress.coerce(value, :integer, @version) @string = IpAddress.coerce(value, :string, @version) end |
Instance Attribute Details
#integer ⇒ Object (readonly)
Returns the value of attribute integer.
58 59 60 |
# File 'lib/ip_address.rb', line 58 def integer @integer end |
#string ⇒ Object (readonly)
Returns the value of attribute string.
58 59 60 |
# File 'lib/ip_address.rb', line 58 def string @string end |
#version ⇒ Object (readonly)
Returns the value of attribute version.
58 59 60 |
# File 'lib/ip_address.rb', line 58 def version @version end |
Class Method Details
.coerce(value, to_type, version = nil) ⇒ Object
Takes an Integer or a String representation of an IP address and coerces it to a representation of the requested type (:integer / :string). If the version (4 / 6) is not specified then it will be guessed with guess_version.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/ip_address.rb', line 9 def self.coerce(value, to_type, version = nil) raise "unknown type #{to_type.inspect} requested" unless [:integer, :string].include?(to_type) version ||= guess_version(value) case value when Integer if to_type == :integer then value elsif version == 4 then [24, 16, 8, 0].map { |shift| (value >> shift) & 255 }.join(".") else sprintf("%.32x", value).scan(/.{4}/).join(":") end when String if to_type == :string then value elsif version == 4 then value.split(".").inject(0) { |total, octet| (total << 8) + octet.to_i } else value.delete(":").to_i(16) end end end |
.guess_version(value) ⇒ Object
Takes an Integer or a String and guesses whether it represents an IPv4 or IPv6 address. For an Integer, IPv4 is assumed unless the value is greater than IP_MAX. For a String, IPv6 is assumed if it contains at least one colon (:).
30 31 32 33 34 35 |
# File 'lib/ip_address.rb', line 30 def self.guess_version(value) case value when Integer then value > IP_MAX[4] ? 6 : 4 when String then value =~ /:/ ? 6 : 4 end end |
.mask_from_slash_bits(bits, version = nil) ⇒ Object
Takes an Integer bitcount (bits) and returns an appropriate masking Integer. For example, a /24 network (in IPv4) corresponds to a mask of 255.255.255.0 or the number 4294967040. If the version (4 / 6) is not specified then it will be assumed to be 4 unless bits > 32.
40 41 42 43 44 45 46 47 |
# File 'lib/ip_address.rb', line 40 def self.mask_from_slash_bits(bits, version = nil) raise "bits > 128" if bits > 128 version ||= bits > 32 ? 6 : 4 max = IP_MAX[version] left_shift = IP_BITS[version] - bits (max << left_shift) & max end |
.mask_size(value, version = nil) ⇒ Object
Takes an Integer or a String representation of a network mask and returns the number of addresses it encodes. If the version (4 / 6) is not specified then it will be guessed with guess_version.
51 52 53 54 |
# File 'lib/ip_address.rb', line 51 def self.mask_size(value, version = nil) version ||= guess_version(value) (coerce(value, :integer, version) ^ IP_MAX[version]) + 1 end |
Instance Method Details
#+(value) ⇒ Object
Adds the specified Integer value to that of the IpAddress and returns a new IpAddress based on the sum.
69 70 71 |
# File 'lib/ip_address.rb', line 69 def +(value) IpAddress.new(@integer + value, @version) end |
#-(value) ⇒ Object
Subtracts the specified Integer value from that of the IpAddress and returns a new IpAddress based on the difference.
74 75 76 |
# File 'lib/ip_address.rb', line 74 def -(value) IpAddress.new(@integer - value, @version) end |
#/(bits) ⇒ Object
Returns the range of IpAddresses in the specified /bits network. Basically a convenience wrapper around mask.
79 80 81 |
# File 'lib/ip_address.rb', line 79 def /(bits) mask(IpAddress.mask_from_slash_bits(bits, @version)) end |
#<=>(other) ⇒ Object
Compares one IpAddress with another based on the Integer representation of their values.
84 85 86 |
# File 'lib/ip_address.rb', line 84 def <=>(other) @integer <=> other.integer end |
#mask(value) ⇒ Object
Takes an Integer or a String representation of a network mask and returns the range of IpAddresses in that network.
89 90 91 92 |
# File 'lib/ip_address.rb', line 89 def mask(value) base_int = @integer & IpAddress.coerce(value, :integer, @version) IpAddressRange.new(IpAddress.new(base_int, @version), IpAddress.new(base_int + IpAddress.mask_size(value, @version) - 1)) end |
#succ ⇒ Object
Returns the next IpAddress after this one.
95 96 97 |
# File 'lib/ip_address.rb', line 95 def succ self + 1 end |
#to_i ⇒ Object
99 100 101 |
# File 'lib/ip_address.rb', line 99 def to_i @integer end |
#to_s ⇒ Object
103 104 105 |
# File 'lib/ip_address.rb', line 103 def to_s @string end |