ip_address 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. data.tar.gz.sig +0 -0
  2. data/lib/ip_address.rb +167 -0
  3. metadata +87 -0
  4. metadata.gz.sig +1 -0
data.tar.gz.sig ADDED
Binary file
data/lib/ip_address.rb ADDED
@@ -0,0 +1,167 @@
1
+ #!/usr/bin/ruby
2
+
3
+ class NotAnIPError < Exception
4
+ def initialize(not_an_ip)
5
+ super("#{not_an_ip.inspect} isn't a valid IP address")
6
+ end
7
+ end
8
+
9
+ # This class represents an IP address.
10
+ class IPAddress
11
+ # Things that match this are (mostly) IPs.
12
+ IP_REGEXP = /^(?:\d{1,3}\.){3}\d{1,3}$/
13
+
14
+ # Is _addr_ a string representation of an IP (without a netmask)?
15
+ def self.is_an_ip?(addr)
16
+ !!( IP_REGEXP =~ addr and addr.split(".").all?{|x| x.to_i < 256} )
17
+ end
18
+
19
+ # our netmask
20
+ attr_reader :netmask
21
+
22
+ # Set our netmask to _val_.
23
+ def netmask=(val)
24
+ @ip = mask(@ip, val)
25
+ @netmask = val
26
+ end
27
+
28
+ # @overload new(ip)
29
+ # @param [String] ip an IP like "12.4.97.8"
30
+ # @overload new(ip)
31
+ # @param [String] ip an IP like "12.4.97.0/24"
32
+ # @overload new(ip)
33
+ # @param [String] ip an IP like [12, 4, 97, 8]
34
+ # @overload new(ip)
35
+ # @param [IPAddress] ip another IPAddress instance
36
+ # @overload new(ip)
37
+ # @param [Fixnum] ip an IP like (12*256**3 + 4*256**2 + 97*256 + 8)
38
+ def initialize(ip)
39
+ @ip, nmask = any_to_int_and_netmask(ip)
40
+
41
+ self.netmask = nmask
42
+ end
43
+
44
+ # Get our _indx_th quad.
45
+ # @example
46
+ # IPAddress.new("12.4.97.8")[1] #=> 4
47
+ def [](index)
48
+ unless (0..3) === index
49
+ raise ArgumentError, "there are four parts to an IP address"
50
+ end
51
+
52
+ to_a[index]
53
+ end
54
+
55
+ # Set our _index_th quad to the integer _val_.
56
+ # @example
57
+ # ip = IPAddress.new("12.4.97.0")
58
+ # ip[3] = 8
59
+ # ip #=> #<IPAddress: 12.4.97.8>
60
+ def []=(index, val)
61
+ if not (0..3) === index
62
+ raise ArgumentError, "there are four parts to an IP address"
63
+ elsif not (0..256) === val
64
+ raise ArgumentError, "each of the IP parts is between 0 and 256"
65
+ end
66
+
67
+ ip_as_array = to_a
68
+ ip_as_array[index] = val
69
+ @ip, @netmask = any_to_int_and_netmask(ip_as_array)
70
+
71
+ val
72
+ end
73
+
74
+ # our quads
75
+ def to_a
76
+ int_to_array(@ip)
77
+ end
78
+
79
+ def to_s
80
+ to_a.join(".") + (@netmask == 32 ? "" : "/#{@netmask}")
81
+ end
82
+
83
+ def to_i
84
+ @ip
85
+ end
86
+
87
+ def inspect
88
+ "#<#{self.class}: #{self}>"
89
+ end
90
+
91
+ # Return a new IPAddress instance with a netmask of _nmask_ with an IP the
92
+ # same as ours.
93
+ # @example
94
+ # ip = IPAddress.new("12.4.97.8") / 24 #=> #<IPAddress: 12.4.97.0/24>
95
+ def /(nmask)
96
+ self.class.new(self).tap{|x| x.netmask = nmask}
97
+ end
98
+
99
+ def ==(ip)
100
+ ip = self.class.new(ip) unless ip.is_a? self.class
101
+
102
+ ip.to_i == to_i and ip.netmask == @netmask
103
+ end
104
+
105
+ # Is _ip_ in our IP range?
106
+ def ===(ip)
107
+ self == ( self.class.new(ip) / @netmask )
108
+ end
109
+
110
+ private
111
+ def mask(ip_int, nmask)
112
+ (ip_int >> (32 - nmask)) << (32 - nmask)
113
+ end
114
+
115
+ # Convert an IP address of any of the forms supported by IPAddress#new() to a
116
+ # Fixnum (also described there) and a netmask.
117
+ # @return [Fixnum, Fixnum] something like [201613576, 32]
118
+ def any_to_int_and_netmask(ip)
119
+ case ip
120
+ when /^((?:\d+\.){3}\d+)(?:\/(\d+))?$/
121
+ m = $~
122
+ int_ip = array_to_int(m[1].split(".").map{|x| x.to_i})
123
+ nmask = (m[2] || 32).to_i
124
+
125
+ return int_ip, nmask
126
+
127
+ when Array
128
+ return array_to_int(ip), 32
129
+
130
+ when Integer
131
+ return ip, 32
132
+
133
+ when self.class
134
+ return ip.to_i, ip.netmask
135
+
136
+ else
137
+ raise NotAnIPError.new(ip)
138
+ end
139
+ end
140
+
141
+ # Turn an Array representation of an IP address _array_ to an equivalent
142
+ # Fixnum representation.
143
+ # @param [Array] array an Array like [12, 4, 97, 8]
144
+ # @return [Fixnum] array.reduce{ |x, y| x*256 + y }
145
+ def array_to_int(array)
146
+ unless array.all?{ |i| (0..256) === i } and array.length == 4
147
+ raise NotAnIPError.new(array)
148
+ end
149
+
150
+ return array.reduce{ |x, y| x*256 + y }
151
+ end
152
+
153
+ # Turn a Fixnum representation of an IP address _ip_int_ to its Array
154
+ # equivalent.
155
+ # @param [Fixnum] ip_int something like 201613576
156
+ # @return [Array] something like [12, 4, 97, 8]
157
+ def int_to_array(ip_int)
158
+ ip_array = Array.new
159
+
160
+ 4.times do
161
+ ip_array.unshift( ip_int % 256 )
162
+ ip_int /= 256
163
+ end
164
+
165
+ ip_array
166
+ end
167
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ip_address
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ version: "0.1"
10
+ platform: ruby
11
+ authors:
12
+ - katmagic
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain:
16
+ - |
17
+ -----BEGIN CERTIFICATE-----
18
+ MIIDQDCCAiigAwIBAgIBADANBgkqhkiG9w0BAQUFADBGMRgwFgYDVQQDDA90aGUu
19
+ bWFnaWNhbC5rYXQxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixk
20
+ ARkWA2NvbTAeFw0xMDExMjcwMTQwMTRaFw0xMTExMjcwMTQwMTRaMEYxGDAWBgNV
21
+ BAMMD3RoZS5tYWdpY2FsLmthdDEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYK
22
+ CZImiZPyLGQBGRYDY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
23
+ vVnssXKFL/qdWKIjTbLKZNz+gg78DICoQSVxeO63aSaYMxFtbv0KGXPZDkiFF1Jl
24
+ m9ZIh+iVmoo9UcENk6CqY1BiMTMZ9QnHPdIFOsw3eBujh1wJ9cXybhaoma2apiIS
25
+ CtPYPbTs1ucJ8tZUv2jddnj3hlFB2LRjMCquWs70uYhjOAwLkxAi6mijLyeQ+NCk
26
+ X+wPgYF8mTylt2VbQAQEDtmchURoPtSjc1RTsPmD09JbLVV/5yxqKxZFBP5UfWRy
27
+ ah/sKsDKIu/GonFvX0t4XQGwDRbT39eETQ/zbkLjwb4Mf32r4CrcWUWN8jqLVonB
28
+ p59Fvw9gNb7eC2VvCPuF6QIDAQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE
29
+ sDAdBgNVHQ4EFgQUEirhbP8V735WXh9StgsdQNg5NXkwDQYJKoZIhvcNAQEFBQAD
30
+ ggEBAIkMv0N2VTwBvUeEv036tpOAl91MiweXUoPmLba+/ekzowQDb1Y6zQD+Oi10
31
+ bgae6Je3Vr/t3fewldVLO6zar90rQo9MXa0+QDilogtmDSVQc8gO0eHRnFtix7VM
32
+ wKcje4Ns3w7zE0ztOkGwdTQaDWKFMGwd1es6hnLTOH09vGtaO2Xu39KXijA71XLM
33
+ 0WspZe4zNBRmcdsNUYArw0KOcB3WLFZ2pI9K9rveB7hkwgAn6rSBf8/evZ9qPinZ
34
+ PcrsoLG0ZZxFAoFhlVaxZsQhw8aIev48+0uD9l1cy1+rrYsgL4lHlUzK8tndhR0+
35
+ kCxJ3nT4fqhTbbQYnOuTu8+un3E=
36
+ -----END CERTIFICATE-----
37
+
38
+ date: 2010-11-26 00:00:00 -05:00
39
+ default_executable:
40
+ dependencies: []
41
+
42
+ description: Easily manipulate IPv4 addresses.
43
+ email: the.magical.kat@gmail.com
44
+ executables: []
45
+
46
+ extensions: []
47
+
48
+ extra_rdoc_files: []
49
+
50
+ files:
51
+ - lib/ip_address.rb
52
+ has_rdoc: true
53
+ homepage: https://github.com/katmagic/ip_address
54
+ licenses:
55
+ - Unlicense (http://unlicense.org)
56
+ post_install_message:
57
+ rdoc_options: []
58
+
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ hash: 3
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ requirements: []
80
+
81
+ rubyforge_project: ip_address
82
+ rubygems_version: 1.3.7
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: Work with IP addresses.
86
+ test_files: []
87
+
metadata.gz.sig ADDED
@@ -0,0 +1 @@
1
+ Z�$.���:{���a0��&G�����_J�Zd����ݴ�S�9�[��*�w���r�-Z��Ĥ�T�p>/p�@T�"���%��7th�C���;��Z��������;��m�P]iܩ�����>�w�i���4�4�`����$���]+��O��t/QtY��]%~����A)�<C-3�c"&�ޱ�/�憄���R�J[+ r�گ�Q�5n� ���T�ڎ�!Cl�?�\|ڞ�$ ����DGi�Z��ҥ`�,WU������|