Module: IpGeoLookup::IpAddress

Defined in:
lib/ip_geo_lookup/ip_address.rb

Class Method Summary collapse

Class Method Details

.parse(ip_string) ⇒ Object

Returns [integer, version] or nil. Rejects leading-zero octets.



8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/ip_geo_lookup/ip_address.rb', line 8

def parse(ip_string)
  return nil unless ip_string.is_a?(String)

  addr = ip_string.strip
  if addr.include?(":")
    int = to_i_v6(addr)
    int ? [int, 6] : nil
  elsif addr.include?(".")
    int = to_i(addr)
    int ? [int, 4] : nil
  end
end

.to_i(ip_string) ⇒ Object

IPv4 string to 32-bit integer. Rejects leading-zero octets.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/ip_geo_lookup/ip_address.rb', line 22

def to_i(ip_string)
  return nil unless ip_string.is_a?(String)

  octets = ip_string.strip.split(".")
  return nil unless octets.length == 4

  result = 0
  octets.each do |octet|
    return nil unless octet.match?(/\A(0|[1-9]\d{0,2})\z/)
    value = octet.to_i
    return nil if value > 255
    result = (result << 8) | value
  end
  result
end

.to_i_v6(ip_string) ⇒ Object

IPv6 string to 128-bit integer. Supports

shorthand.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/ip_geo_lookup/ip_address.rb', line 39

def to_i_v6(ip_string)
  return nil unless ip_string.is_a?(String)

  addr = ip_string.strip.downcase
  return nil if addr.empty? || addr.include?("%")

  if addr.include?("::")
    return nil if addr.scan("::").length > 1

    left, right = addr.split("::", -1)
    left_groups = left.empty? ? [] : left.split(":")
    right_groups = right.empty? ? [] : right.split(":")
    fill_count = 8 - left_groups.length - right_groups.length
    return nil if fill_count < 0

    groups = left_groups + Array.new(fill_count, "0") + right_groups
  else
    groups = addr.split(":")
  end

  return nil unless groups.length == 8

  result = 0
  groups.each do |group|
    return nil unless group.match?(/\A[0-9a-f]{1,4}\z/)
    result = (result << 16) | group.to_i(16)
  end
  result
end