best_ip 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in best_ip.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 mj
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # BestIp
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'best_ip'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install best_ip
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/best_ip.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'best_ip/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "best_ip"
8
+ gem.version = BestIp::VERSION
9
+ gem.authors = ["mj"]
10
+ gem.email = ["tywf91@gmail.com"]
11
+ gem.description = %q{用ip确定用户位置}
12
+ gem.summary = %q{用ip确定用户位置}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
@@ -0,0 +1,3 @@
1
+ module BestIp
2
+ VERSION = "0.0.1"
3
+ end
data/lib/best_ip.rb ADDED
@@ -0,0 +1,146 @@
1
+ require "best_ip/version"
2
+
3
+ module BestIp
4
+ class IpSearch
5
+ def initialize(file='lib/qqwry.dat')
6
+ filename = file
7
+ @file = File.open(filename,"r")
8
+ @index_first,@index_last = @file.read(8).unpack('L2')
9
+ @index_total = (@index_last - @index_first)/7 + 1
10
+ @location = {}
11
+ end
12
+
13
+ #把IP转换为长整形
14
+ def ip2long(ip)
15
+ long = 0
16
+ ip.split(/\./).each_with_index do |b, i|
17
+ long += b.to_i << 8*(3-i)
18
+ end
19
+ long
20
+ end
21
+
22
+ #读取偏移值
23
+ def read_offset(position)
24
+ @file.seek position
25
+ chars = @file.read(3).unpack('C3')
26
+ (chars[2]<<16) + (chars[1]<<8) + chars[0]
27
+ end
28
+
29
+ #读取记录中的4字节作为一个long值
30
+ def read_long(position)
31
+ @file.seek position
32
+ @file.read(4).unpack('L')[0]
33
+ end
34
+
35
+ #读取模式信息,1和2为正常,其他值异常
36
+ #position:字符串偏移量
37
+ def read_mode(position)
38
+ @file.seek position #前4位为IP值
39
+ @file.read(1).unpack('C')[0]
40
+ end
41
+
42
+ #根据IP在索引中查找具体位置
43
+ def find_str_offset(ip_long)
44
+ offset_min,offset_max = @index_first,@index_last
45
+
46
+ while offset_min <= offset_max
47
+ offset_mid = offset_min + (offset_max - offset_min) / 14*7
48
+ mid = read_long(offset_mid)
49
+
50
+ if ip_long < mid
51
+ offset_max = offset_mid - 7
52
+ elsif ip_long == mid
53
+ return read_offset(offset_mid+4)
54
+ else
55
+ offset_min = offset_mid + 7
56
+ end
57
+ end
58
+
59
+ return read_offset(offset_max+4)
60
+ end
61
+
62
+ #读取字符串
63
+ def read_str(position)
64
+ @file.seek position
65
+ str = []
66
+ while c = @file.getc
67
+ break if str.size > 60 #地址不会太长,防止有异常数据
68
+ break if c == "\0" #地址字符串以\0结尾
69
+ str << c
70
+ end
71
+ str.join ''
72
+ end
73
+
74
+ #根据IP查找地址
75
+ def find_ip_location(ip)
76
+ offset = find_str_offset(ip2long(ip))#读取具体数据在记录区的偏移
77
+ @location = {}
78
+ case read_mode(offset+4)
79
+ when 1
80
+ str_offset = read_offset(offset+4+1) #读取字符串存储位置偏移(4是IP值,1是模式)
81
+ if read_mode(str_offset)==2 then
82
+ country_offset = read_offset(str_offset+1)
83
+ @location[:country] = read_str country_offset
84
+ @location[:area] = read_area(str_offset+4)
85
+ else
86
+ @location[:country] = read_str str_offset
87
+ @location[:area] = read_area(@file.pos)
88
+ end
89
+
90
+ when 2
91
+ str_offset = read_offset(offset+4+1) #读取字符串存储位置偏移(4是IP值,1是模式)
92
+ @location[:country] = read_str(str_offset)
93
+ @location[:area] = read_area(offset+8)
94
+ else
95
+ @location[:country] = read_str(offset)
96
+ @location[:area] = read_str(@file.pos)
97
+ end
98
+
99
+ @location
100
+ end
101
+
102
+ #读取记录中的地址信息
103
+ def read_area(position)
104
+ mode = read_mode(position)
105
+ if mode==1 || mode==2
106
+ offset = read_offset(position+1)
107
+ return '' if offset==0
108
+ return read_str(offset)
109
+ else
110
+ return read_str(position)
111
+ end
112
+ end
113
+
114
+ #取得国家,UTF8编码
115
+ def country
116
+ @location[:country].encode('UTF-8','GB2312')
117
+ end
118
+
119
+ #取得地区,UTF8编码
120
+ def area
121
+ @location[:area].encode('UTF-8','GB2312')
122
+ end
123
+
124
+ #取得国家,GB2312编码
125
+ def country_gb
126
+ @location[:country]
127
+ end
128
+
129
+ #取得地区,GB2312编码
130
+ def area_gb
131
+ @location[:area]
132
+ end
133
+ end
134
+
135
+ class Ip
136
+ def initialize(ip="")
137
+ @ip = ip
138
+ end
139
+
140
+ def location()
141
+ is = IpSearch.new
142
+ is.find_ip_location(@ip)
143
+ return is.country
144
+ end
145
+ end
146
+ end
data/lib/qqwry.dat ADDED
Binary file
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: best_ip
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - mj
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-21 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: 用ip确定用户位置
15
+ email:
16
+ - tywf91@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - Gemfile
23
+ - LICENSE.txt
24
+ - README.md
25
+ - Rakefile
26
+ - best_ip.gemspec
27
+ - lib/best_ip.rb
28
+ - lib/best_ip/version.rb
29
+ - lib/qqwry.dat
30
+ homepage: ''
31
+ licenses: []
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ! '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ requirements: []
49
+ rubyforge_project:
50
+ rubygems_version: 1.8.24
51
+ signing_key:
52
+ specification_version: 3
53
+ summary: 用ip确定用户位置
54
+ test_files: []