ipip 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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