From 1dd5df1ce76984c613f824d91da64409fe256133 Mon Sep 17 00:00:00 2001 From: Pat Downey Date: Tue, 22 May 2012 16:28:34 +0100 Subject: [PATCH 1/2] Add eql? and hash definitions so that instances of IPAddress and Prefix behave as expected when used in sets or hashes. --- lib/ipaddress/ipv4.rb | 10 +++++++++- lib/ipaddress/ipv6.rb | 8 ++++++++ lib/ipaddress/prefix.rb | 10 +++++++++- test/ipaddress/ipv4_test.rb | 9 ++++++++- test/ipaddress/ipv6_test.rb | 7 +++++++ test/ipaddress/prefix_test.rb | 7 +++++++ 6 files changed, 48 insertions(+), 3 deletions(-) diff --git a/lib/ipaddress/ipv4.rb b/lib/ipaddress/ipv4.rb index a798a24..56e5bf9 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 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..33df98c 100644 --- a/test/ipaddress/ipv4_test.rb +++ b/test/ipaddress/ipv4_test.rb @@ -526,7 +526,14 @@ 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 + 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 From 92e2a4060c530ac733e946eed40d2e62f89530eb Mon Sep 17 00:00:00 2001 From: Pat Downey Date: Wed, 19 Dec 2012 19:19:48 +0000 Subject: [PATCH 2/2] in IPv4::subnet convert subprefix to integer in case subprefix is an IPAddress::Prefix instance. --- lib/ipaddress/ipv4.rb | 8 +++++--- test/ipaddress/ipv4_test.rb | 8 ++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/ipaddress/ipv4.rb b/lib/ipaddress/ipv4.rb index 56e5bf9..34685a2 100644 --- a/lib/ipaddress/ipv4.rb +++ b/lib/ipaddress/ipv4.rb @@ -688,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/test/ipaddress/ipv4_test.rb b/test/ipaddress/ipv4_test.rb index 33df98c..d0032ab 100644 --- a/test/ipaddress/ipv4_test.rb +++ b/test/ipaddress/ipv4_test.rb @@ -534,6 +534,14 @@ def test_hash_equality 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