Class: IpLocationCn::QqWry
- Inherits:
-
Object
- Object
- IpLocationCn::QqWry
- Includes:
- Singleton
- Defined in:
- lib/ip_location_cn/qq_wry.rb
Instance Method Summary collapse
-
#find_ip_location(ip) ⇒ Object
根据IP查找地址.
-
#find_str_offset(ip_long) ⇒ Object
根据IP在索引中查找具体位置.
-
#initialize ⇒ QqWry
constructor
A new instance of QqWry.
-
#ip2long(ip) ⇒ Object
把IP转换为长整形.
-
#read_long(position) ⇒ Object
读取记录中的4字节作为一个long值.
-
#read_mode(position) ⇒ Object
读取模式信息,1和2为正常,其他值异常 position:字符串偏移量.
-
#read_offset(position) ⇒ Object
读取偏移值.
-
#read_origin(position) ⇒ Object
读取记录中的地址信息.
-
#read_str(position) ⇒ Object
读取字符串.
Constructor Details
#initialize ⇒ QqWry
Returns a new instance of QqWry.
6 7 8 9 10 11 12 |
# File 'lib/ip_location_cn/qq_wry.rb', line 6 def initialize data_file_path = File.("../../data/qqwry.dat", __FILE__) @data_file = File.open data_file_path, 'r' @index_first, @index_last = @data_file.read(8).unpack('L2') @index_total = (@index_last - @index_first) / 7 + 1 @location = {} end |
Instance Method Details
#find_ip_location(ip) ⇒ Object
根据IP查找地址
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/ip_location_cn/qq_wry.rb', line 85 def find_ip_location(ip) offset = find_str_offset(ip2long(ip))#读取具体数据在记录区的偏移 @location = {} case read_mode(offset + 4) when 1 str_offset = read_offset(offset + 4 + 1) #读取字符串存储位置偏移(4是IP值,1是模式) if read_mode(str_offset) == 2 then location_offset = read_offset(str_offset+1) @location[:location] = read_str location_offset @location[:origin] = read_origin(str_offset+4) else @location[:location] = read_str str_offset @location[:origin] = read_origin(@data_file.pos) end when 2 str_offset = read_offset(offset + 4 + 1) #读取字符串存储位置偏移(4是IP值,1是模式) @location[:location] = read_str(str_offset) @location[:origin] = read_origin(offset + 8) else @location[:location] = read_str(offset) @location[:origin] = read_str(@data_file.pos) end @location end |
#find_str_offset(ip_long) ⇒ Object
根据IP在索引中查找具体位置
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/ip_location_cn/qq_wry.rb', line 46 def find_str_offset(ip_long) offset_min, offset_max = @index_first, @index_last while offset_min <= offset_max offset_mid = offset_min + (offset_max - offset_min) / 14 * 7 mid = read_long(offset_mid) if ip_long < mid offset_max = offset_mid - 7 elsif ip_long == mid return read_offset(offset_mid+4) else offset_min = offset_mid + 7 end end return read_offset(offset_max + 4) end |
#ip2long(ip) ⇒ Object
把IP转换为长整形
76 77 78 79 80 81 82 |
# File 'lib/ip_location_cn/qq_wry.rb', line 76 def ip2long(ip) long = 0 ip.split(/\./).each_with_index do |b, i| long += b.to_i << 8 * (3 - i) end long end |
#read_long(position) ⇒ Object
读取记录中的4字节作为一个long值
22 23 24 25 |
# File 'lib/ip_location_cn/qq_wry.rb', line 22 def read_long(position) @data_file.seek position @data_file.read(4).unpack('L')[0] end |
#read_mode(position) ⇒ Object
读取模式信息,1和2为正常,其他值异常 position:字符串偏移量
28 29 30 31 |
# File 'lib/ip_location_cn/qq_wry.rb', line 28 def read_mode(position) @data_file.seek position #前4位为IP值 @data_file.read(1).unpack('C')[0] end |
#read_offset(position) ⇒ Object
读取偏移值
15 16 17 18 19 |
# File 'lib/ip_location_cn/qq_wry.rb', line 15 def read_offset(position) @data_file.seek position chars = @data_file.read(3).unpack('C3') (chars[2] << 16) + (chars[1] << 8) + chars[0] end |
#read_origin(position) ⇒ Object
读取记录中的地址信息
34 35 36 37 38 39 40 41 42 43 |
# File 'lib/ip_location_cn/qq_wry.rb', line 34 def read_origin(position) mode = read_mode(position) if mode == 1 || mode == 2 offset = read_offset(position + 1) return '' if offset == 0 return read_str(offset) else return read_str(position) end end |
#read_str(position) ⇒ Object
读取字符串
64 65 66 67 68 69 70 71 72 73 |
# File 'lib/ip_location_cn/qq_wry.rb', line 64 def read_str(position) @data_file.seek position str = [] while c = @data_file.getc break if str.size > 60 #地址不会太长,防止有异常数据 break if c == "\0" #地址字符串以\0结尾 str << c end str.join '' end |