class IPIP::IPv4Database
Database for search IPv4 address.
The IPIP.net data file(17monipdb.dat) format in bytes:: --------------------------- | 4 bytes | <- offset number --------------------------- | 256 * 4 bytes | <- first ip number index --------------------------- | offset - 1024 - 4 bytes | <- ip index --------------------------- | data storage | ---------------------------
Constants
- DEFAULT_DATA_FILE
- FIRST_IP_NUMBER_INDEX_SIZE
- IP_BLOCK_SIZE
- OFFSET_NUMBER_SIZE
Public Class Methods
new(data_file = nil)
click to toggle source
# File lib/ipip/ipv4_database.rb, line 27 def initialize(data_file = nil) @data_file = data_file || DEFAULT_DATA_FILE end
Public Instance Methods
find(ip)
click to toggle source
# File lib/ipip/ipv4_database.rb, line 31 def find(ip) ip = IPSocket::getaddress(ip) lookup_ipv4(ip) end
Private Instance Methods
binread(length, offset)
click to toggle source
# File lib/ipip/ipv4_database.rb, line 46 def binread(length, offset) IO.binread(@data_file, length, offset) end
buffer()
click to toggle source
# File lib/ipip/ipv4_database.rb, line 42 def buffer @buffer ||= binread(nil, OFFSET_NUMBER_SIZE) end
lookup_ipv4(ip)
click to toggle source
# File lib/ipip/ipv4_database.rb, line 50 def lookup_ipv4(ip) ip = IPAddr.new(ip) return unless ip.ipv4? nip = ip.hton first_ip = unpack_C(nip) first_ip_offset = first_ip * 4 start = unpack_V(buffer[first_ip_offset, 4]) start_offset = start * IP_BLOCK_SIZE + FIRST_IP_NUMBER_INDEX_SIZE lo, hi = 0, (offset - start_offset) / IP_BLOCK_SIZE while lo < hi mid = (lo + hi) / 2 mid_offset = start_offset + mid * IP_BLOCK_SIZE mid_val = buffer[mid_offset, 4] if mid_val < nip lo = mid + 1 else hi = mid end end start_offset += lo * IP_BLOCK_SIZE return if start_offset == offset data_pos = unpack_V(buffer[start_offset + 4, 3] + 0.chr) data_length = unpack_C(buffer[start_offset + 7]) data_offset = offset + data_pos - FIRST_IP_NUMBER_INDEX_SIZE - OFFSET_NUMBER_SIZE data = buffer[data_offset, data_length].to_s.encode('UTF-8', 'UTF-8') end
offset()
click to toggle source
# File lib/ipip/ipv4_database.rb, line 38 def offset @offset ||= unpack_N(binread(OFFSET_NUMBER_SIZE, 0)) end