ipip 0.0.3 → 0.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 140cd161487cb7a2d38647384e65490d19410f73
4
- data.tar.gz: 4f04028f59e85fdbf0f961a22f5b54c9e2d21502
3
+ metadata.gz: 7629926327cfecda9e31fa00aa0ad2fb2b593368
4
+ data.tar.gz: 5aa69af8174e1463581956f1f21f0da4fb3ded2a
5
5
  SHA512:
6
- metadata.gz: e6232d58c111f722f27a28a0a8d5f4a2f6293ab2dd86a8e1150aed05408931f67235e23e1c76ac308718bda2fd9308c807b20f798685d05152e66a819b0698c9
7
- data.tar.gz: 9ec8501d3a62e61b0584676a9d34f2ff615e341cbe841a5ed23ad7aa8b4c3554eb1f7633bbef457893b6f387ed5b90707000f7a0fbc484247b862b01fdb92461
6
+ metadata.gz: 2f50de124e40661d26f1867a84709e52af259dafb73c413b84b9f7f867983eae5840c7d8342e63f534bcde422325067c0396d25ab321bd4ed4e09f696b0ae3fb
7
+ data.tar.gz: 715f3af052260f6785da11673219137c7847a2b9b7d967789ab6231337fcf396f9b0e977213ad105ba7b79439c0f0ce648037f7b876fdddacffbb1edfc0218fe
@@ -1,18 +1,56 @@
1
1
  require 'ipip/version'
2
2
  require 'ipip/ipv4_database'
3
+ require 'ipip/ipv4_database_x'
4
+
3
5
 
4
6
  module IPIP
5
7
 
6
- class << IPIP
8
+ class << self
7
9
 
8
10
  def find(ip)
9
11
  ipv4_database.find(ip)
10
12
  end
11
13
 
12
- def ipv4_database(data_file=nil)
14
+ def load_data!(data_file)
15
+ raise 'No such file' unless File.exists?(data_file)
16
+
17
+ ipv4_database(data_file)
18
+ end
19
+
20
+ def ipv4_database(data_file = nil)
13
21
  @ipv4_database ||= IPv4Database.new(data_file)
14
22
  end
15
23
 
16
24
  end
17
25
 
18
26
  end
27
+
28
+
29
+ module IPIPX
30
+
31
+ class << self
32
+
33
+ def find(ip)
34
+ raise 'pls call `IPIPX.load_data!` first' unless data_loaded?
35
+
36
+ ipv4_database.find(ip)
37
+ end
38
+
39
+ def load_data!(data_file)
40
+ raise 'No such file' unless File.exists?(data_file)
41
+
42
+ ipv4_database(data_file)
43
+ @data_was_loaded = true
44
+ end
45
+
46
+ def ipv4_database(data_file = nil)
47
+ @ipv4_database ||= IPv4DatabaseX.new(data_file)
48
+ end
49
+
50
+ def data_loaded?
51
+ @data_was_loaded ||= false
52
+ end
53
+
54
+ end
55
+
56
+ end
Binary file
@@ -24,7 +24,7 @@ module IPIP
24
24
  IP_BLOCK_SIZE = 8
25
25
  DEFAULT_DATA_FILE = File.expand_path("../17monipdb.dat", __FILE__)
26
26
 
27
- def initialize(data_file=nil)
27
+ def initialize(data_file = nil)
28
28
  @data_file = data_file || DEFAULT_DATA_FILE
29
29
  end
30
30
 
@@ -0,0 +1,94 @@
1
+ require 'socket'
2
+ require 'ipaddr'
3
+
4
+ module IPIPX
5
+
6
+ # Database for search IPv4 address.
7
+ #
8
+ # The IPIP.net data file(ipip.datx) format in bytes::
9
+ #
10
+ # ---------------------------
11
+ # | 4 bytes | <- offset number
12
+ # ---------------------------
13
+ # | 256 * 9 bytes | <- first ip number index
14
+ # ---------------------------
15
+ # | offset - 2304 - 4 bytes | <- ip index
16
+ # ---------------------------
17
+ # | data storage |
18
+ # ---------------------------
19
+ #
20
+ class IPv4DatabaseX
21
+
22
+ OFFSET_NUMBER_SIZE = 4
23
+ FIRST_IP_NUMBER_INDEX_SIZE = 256 * 1024
24
+ IP_BLOCK_SIZE = 9
25
+
26
+ def initialize(data_file)
27
+ @data_file = data_file
28
+ end
29
+
30
+ def find(ip)
31
+ ip = IPSocket::getaddress(ip)
32
+ lookup_ipv4(ip)
33
+ end
34
+
35
+ private
36
+
37
+ def offset
38
+ @offset ||= unpack_N(binread(OFFSET_NUMBER_SIZE, 0))
39
+ end
40
+
41
+ def buffer
42
+ @buffer ||= binread(nil, OFFSET_NUMBER_SIZE)
43
+ end
44
+
45
+ def binread(length, offset)
46
+ IO.binread(@data_file, length, offset)
47
+ end
48
+
49
+ def lookup_ipv4(ip)
50
+ ip = IPAddr.new(ip)
51
+ return unless ip.ipv4?
52
+
53
+ nip = ip.hton
54
+
55
+ first_ip = unpack_C(nip)
56
+ ipdot = ip.to_s.split('.')
57
+ first_ip_offset = (first_ip * 256 + ipdot[1].to_i) * 4
58
+
59
+ start = unpack_V(buffer[first_ip_offset, 4])
60
+ start_offset = start * IP_BLOCK_SIZE + FIRST_IP_NUMBER_INDEX_SIZE
61
+
62
+ data_offset = data_length = -1
63
+
64
+ lo, hi = 0, (offset - start_offset) / IP_BLOCK_SIZE
65
+
66
+ while lo < hi
67
+ mid = (lo + hi) / 2
68
+ mid_offset = start_offset + mid * IP_BLOCK_SIZE
69
+ mid_val = buffer[mid_offset, 4]
70
+
71
+ if mid_val < nip
72
+ lo = mid + 1
73
+ else
74
+ hi = mid
75
+ end
76
+ end
77
+
78
+ start_offset += lo * IP_BLOCK_SIZE
79
+ return if start_offset == offset
80
+
81
+ data_offset = unpack_V(buffer[start_offset + 4, 3] + 0.chr)
82
+ data_length = unpack_C(buffer[start_offset + 8])
83
+
84
+ data_offset = offset + data_offset - FIRST_IP_NUMBER_INDEX_SIZE - OFFSET_NUMBER_SIZE
85
+ data = buffer[data_offset, data_length].encode('UTF-8', 'UTF-8')
86
+ end
87
+
88
+ [:C, :N, :V].each do |format|
89
+ define_method "unpack_#{format}" do |binary|
90
+ binary.unpack(format.to_s).first
91
+ end
92
+ end
93
+ end
94
+ end
@@ -1,3 +1,3 @@
1
1
  module IPIP
2
- VERSION = '0.0.3'
2
+ VERSION = '0.1.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ipip
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - liluo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-03 00:00:00.000000000 Z
11
+ date: 2017-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -49,6 +49,7 @@ files:
49
49
  - lib/ipip.rb
50
50
  - lib/ipip/17monipdb.dat
51
51
  - lib/ipip/ipv4_database.rb
52
+ - lib/ipip/ipv4_database_x.rb
52
53
  - lib/ipip/version.rb
53
54
  homepage: https://github.com/liluo/ipip
54
55
  licenses:
@@ -70,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
71
  version: '0'
71
72
  requirements: []
72
73
  rubyforge_project:
73
- rubygems_version: 2.4.8
74
+ rubygems_version: 2.6.8
74
75
  signing_key:
75
76
  specification_version: 4
76
77
  summary: IP search based on ipip.net