diff --git a/lib/ipaddress/ipv4.rb b/lib/ipaddress/ipv4.rb index a798a24..34685a2 100644 --- a/lib/ipaddress/ipv4.rb +++ b/lib/ipaddress/ipv4.rb @@ -461,7 +461,15 @@ def <=>(oth) return prefix <=> oth.prefix if to_u32 == oth.to_u32 to_u32 <=> oth.to_u32 end - + + def eql?(oth) + self == oth + end + + def hash + [ to_u32, prefix.to_u32 ].hash + end + # # Returns the number of IP addresses included # in the network. It also counts the network @@ -680,11 +688,13 @@ def supernet(new_prefix) # a power of two. # def subnet(subprefix) - unless ((@prefix.to_i)..32).include? subprefix + # convert to integer in case subprefix is an IPAddress::Prefix + subprefix_i = subprefix.to_i + unless ((@prefix.to_i)..32).include? subprefix_i raise ArgumentError, "New prefix must be between #@prefix and 32" end - Array.new(2**(subprefix-@prefix.to_i)) do |i| - self.class.parse_u32(network_u32+(i*(2**(32-subprefix))), subprefix) + Array.new(2**(subprefix_i-@prefix.to_i)) do |i| + self.class.parse_u32(network_u32+(i*(2**(32-subprefix_i))), subprefix_i) end end diff --git a/lib/ipaddress/ipv6.rb b/lib/ipaddress/ipv6.rb index 33d4d19..3c601df 100644 --- a/lib/ipaddress/ipv6.rb +++ b/lib/ipaddress/ipv6.rb @@ -482,6 +482,14 @@ def <=>(oth) to_u128 <=> oth.to_u128 end + def eql?(oth) + self == oth + end + + def hash + [ to_u128, prefix.to_u128 ].hash + end + # # Returns the address portion of an IP in binary format, # as a string containing a sequence of 0 and 1 diff --git a/lib/ipaddress/prefix.rb b/lib/ipaddress/prefix.rb index f3d585d..77ff8b9 100644 --- a/lib/ipaddress/prefix.rb +++ b/lib/ipaddress/prefix.rb @@ -53,6 +53,14 @@ def <=>(oth) @prefix <=> oth.to_i end + def eql?(oth) + self == oth + end + + def hash + to_i.hash + end + # # Sums two prefixes or a prefix to a # number, returns a Fixnum @@ -260,6 +268,6 @@ def host_prefix 128 - @prefix end - end # class Prefix123 < Prefix + end # class Prefix128 < Prefix end # module IPAddress diff --git a/test/ipaddress/ipv4_test.rb b/test/ipaddress/ipv4_test.rb index 6d6386f..d0032ab 100644 --- a/test/ipaddress/ipv4_test.rb +++ b/test/ipaddress/ipv4_test.rb @@ -526,7 +526,22 @@ def test_classmethod_parse_classful end assert_raise(ArgumentError){ @klass.parse_classful("192.168.256.257") } end - + + def test_hash_equality + ip1 = @klass.new("10.0.1.1/24") + ip2 = @klass.new("10.0.1.1/24") + assert_equal ip1.hash, ip2.hash + assert_equal ip1.eql?( ip2 ), true + end + + def test_subnet_prefix_acceptance + ip = @klass.new("10.0.1.1/24") + ip2 = @klass.new("10.0.1.1/29") + subnet1 = ip.subnet(29) + subnet2 = ip.subnet(ip2.prefix) + assert_equal subnet1, subnet2 + end + end # class IPv4Test diff --git a/test/ipaddress/ipv6_test.rb b/test/ipaddress/ipv6_test.rb index 9d9ff3e..34cf6f2 100644 --- a/test/ipaddress/ipv6_test.rb +++ b/test/ipaddress/ipv6_test.rb @@ -418,5 +418,12 @@ def test_method_ipv6? def test_mapped? assert_equal true, @ip.mapped? end + + def test_hash_equality + ip1 = @klass.new("2001:db8::8:800:200c:417a/64") + ip2 = @klass.new("2001:db8::8:800:200c:417a/64") + assert_equal ip1.hash, ip2.hash + assert_equal ip1.eql?( ip2 ), true + end end # class IPv6MappedTest diff --git a/test/ipaddress/prefix_test.rb b/test/ipaddress/prefix_test.rb index bff812e..6e523b5 100644 --- a/test/ipaddress/prefix_test.rb +++ b/test/ipaddress/prefix_test.rb @@ -156,4 +156,11 @@ def test_method_to_u32 end end + def test_hash_equality + prefix1 = @klass.new(23) + prefix2 = @klass.new(23) + assert_equal prefix1.hash, prefix2.hash + assert_equal prefix1.eql?( prefix2 ), true + end + end # class Prefix128Test