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.
- data.tar.gz.sig +0 -0
- data/lib/ip_address.rb +167 -0
- metadata +87 -0
- 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������|
|