ip2location_ruby 8.3.1 → 8.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -2
- data/LICENSE.txt +1 -1
- data/README.md +28 -4
- data/VERSION +1 -1
- data/example.rb +42 -31
- data/ip2location_ruby.gemspec +5 -4
- data/lib/ip2location_ruby.rb +243 -17
- data/spec/ip2location_ruby_iptools_spec.rb +94 -0
- data/spec/ip2location_ruby_webservice_spec.rb +1 -1
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f7f7cc867aa07b3595ae89b5f5fa55fab2b210236b106fa8ad10ccb5b9dd15b1
|
4
|
+
data.tar.gz: 36b720b84b89cfaad323c1d695e1b5408eca69476197cdb7911cdb614856c5e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a84781d5ab63cee79729be08a0ebdc1f3866630b8f00e4aea983e654c2cf55fd66370d8006666c76880621231fd91d9ddf3f19c2efdd0d7b7fde9428f630935
|
7
|
+
data.tar.gz: d6e40740c7fa84c5410239e93f54502e197a19dcc8c00b8a1d30bec76660a35bb9dfe78bced75ae7b4b3c15e29ad9f7e339a1b817e4b28cc4aff99caaf58f624
|
data/Gemfile.lock
CHANGED
@@ -4,7 +4,7 @@ GEM
|
|
4
4
|
bindata (2.4.10)
|
5
5
|
diff-lcs (1.1.3)
|
6
6
|
json (>= 2.3.0)
|
7
|
-
rdoc (3.
|
7
|
+
rdoc (>= 6.3.1)
|
8
8
|
json (~> 1.4)
|
9
9
|
rspec (2.8.0)
|
10
10
|
rspec-core (~> 2.8.0)
|
@@ -21,5 +21,5 @@ PLATFORMS
|
|
21
21
|
DEPENDENCIES
|
22
22
|
bindata
|
23
23
|
bundler (>= 1.2.0)
|
24
|
-
rdoc (
|
24
|
+
rdoc (>= 6.3.1)
|
25
25
|
rspec (~> 2.8.0)
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -9,10 +9,19 @@ Supported IPv4 and IPv6 address.
|
|
9
9
|
For more details, please visit:
|
10
10
|
[https://www.ip2location.com/developers/ruby](https://www.ip2location.com/developers/ruby)
|
11
11
|
|
12
|
+
# INSTALLATION
|
13
|
+
Install this package using the command as below:
|
14
|
+
|
15
|
+
```
|
16
|
+
gem install ip2location_ruby
|
17
|
+
```
|
18
|
+
|
12
19
|
# Usage
|
13
20
|
You can check the **example.rb** file to learn more about usage.
|
14
21
|
|
15
22
|
## BIN Database
|
23
|
+
An outdated BIN database was provided in the library for your testing. You are recommended to visit the [links](#dependencies) to download the latest BIN database and save it in the ```rb``` folder.
|
24
|
+
|
16
25
|
Below is the description of the functions available in the **BIN Database** lookup.
|
17
26
|
|
18
27
|
| Function Name | Description |
|
@@ -45,8 +54,7 @@ Below is the description of the functions available in the **BIN Database** look
|
|
45
54
|
| get_elevation | Return average height of city above sea level in meters (m). |
|
46
55
|
| get_usagetype | Return the ISP's usage type of IP address. |
|
47
56
|
| get_addresstype | Returns the IP address type (A-Anycast, B-Broadcast, M-Multicast & U-Unicast) of IP address or domain name. |
|
48
|
-
|
|
49
|
-
|
57
|
+
| get_category | Returns the IAB content taxonomy category of IP address or domain name. |
|
50
58
|
|
51
59
|
## Web Service
|
52
60
|
Below is the description of the functions available in the **Web Service** lookup.
|
@@ -57,13 +65,29 @@ Below is the description of the functions available in the **Web Service** looku
|
|
57
65
|
| lookup | Return the IP information in array.<ul><li>country_code</li><li>country_name</li><li>region_name</li><li>city_name</li><li>latitude</li><li>longitude</li><li>zip_code</li><li>time_zone</li><li>isp</li><li>domain</li><li>net_speed</li><li>idd_code</li><li>area_code</li><li>weather_station_code</li><li>weather_station_name</li><li>mcc</li><li>mnc</li><li>mobile_brand</li><li>elevation</li><li>usage_type</li><li>address_type</li><li>category</li><li>continent<ul><li>name</li><li>code</li><li>hemisphere</li><li>translations</li></ul></li><li>country<ul><li>name</li><li>alpha3_code</li><li>numeric_code</li><li>demonym</li><li>flag</li><li>capital</li><li>total_area</li><li>population</li><li>currency<ul><li>code</li><li>name</li><li>symbol</li></ul></li><li>language<ul><li>code</li><li>name</li></ul></li><li>idd_code</li><li>tld</li><li>translations</li></ul></li><li>region<ul><li>name</li><li>code</li><li>translations</li></ul></li><li>city<ul><li>name</li><li>translations</li></ul></li><li>geotargeting<ul><li>metro</li></ul></li><li>country_groupings</li><li>time_zone_info<ul><li>olson</li><li>current_time</li><li>gmt_offset</li><li>is_dst</li><li>sunrise</li><li>sunset</li></ul></li><ul> |
|
58
66
|
| get_credit | Return remaining credit of the web service account. |
|
59
67
|
|
68
|
+
## IpTools
|
69
|
+
Below is the description of the functions available in the **IpTools** class.
|
70
|
+
|
71
|
+
| Function Name | Description |
|
72
|
+
|---|---|
|
73
|
+
| is_ipv4 | Return either true or false. Verify if a string is a valid IPv4 address. |
|
74
|
+
| is_ipv6 | Return either true or false. Verify if a string is a valid IPv6 address. |
|
75
|
+
| ipv4_to_decimal | Translate IPv4 address from dotted-decimal address to decimal format. Return null on error. |
|
76
|
+
| decimal_to_ipv4 | Translate IPv4 address from decimal number to dotted-decimal address. Return null on error. |
|
77
|
+
| ipv6_to_decimal | Translate IPv6 address from hexadecimal address to decimal format. Return null on error. |
|
78
|
+
| decimal_to_ipv6 | Translate IPv6 address from decimal number into hexadecimal address. Return null on error. |
|
79
|
+
| ipv4_to_cidr | Convert IPv4 range into a list of IPv4 CIDR notation. |
|
80
|
+
| cidr_to_ipv4 | Convert IPv4 CIDR notation into a list of IPv4 addresses. |
|
81
|
+
| ipv6_to_cidr | Convert IPv6 range into a list of IPv6 CIDR notation. |
|
82
|
+
| cidr_to_ipv6 | Convert IPv6 CIDR notation into a list of IPv6 addresses. |
|
83
|
+
| compress_ipv6 | Compress a IPv6 to shorten the length. |
|
84
|
+
| expand_ipv6 | Expand a shorten IPv6 to full length. |
|
85
|
+
|
60
86
|
# Dependencies
|
61
87
|
This library requires IP2Location BIN data file to function. You may download the BIN data file at
|
62
88
|
* IP2Location LITE BIN Data (Free): https://lite.ip2location.com
|
63
89
|
* IP2Location Commercial BIN Data (Comprehensive): https://www.ip2location.com
|
64
90
|
|
65
|
-
An outdated BIN database was provided in the library for your testing. You are recommended to visit the above links to download the latest BIN database.
|
66
|
-
|
67
91
|
You can also sign up for [IP2Location Web Service](https://www.ip2location.com/web-service/ip2location) to lookup by IP2Location API.
|
68
92
|
|
69
93
|
# IPv4 BIN vs IPv6 BIN
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
8.
|
1
|
+
8.5.0
|
data/example.rb
CHANGED
@@ -4,40 +4,51 @@ require 'ip2location_ruby'
|
|
4
4
|
i2l = Ip2location.new.open("./data/IP2LOCATION-LITE-DB1.IPV6.BIN")
|
5
5
|
record = i2l.get_all('8.8.8.8')
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
print 'Usage Type: ' + record['usagetype'] + "\n"
|
33
|
-
print 'Address Type: ' + record['addresstype'] + "\n"
|
34
|
-
print 'Category: ' + record['category'] + "\n"
|
7
|
+
puts 'Country Code: ' + record['country_short']
|
8
|
+
puts 'Country Name: ' + record['country_long']
|
9
|
+
puts 'Region Name: ' + record['region']
|
10
|
+
puts 'City Name: ' + record['city']
|
11
|
+
puts 'Latitude: '
|
12
|
+
puts record['latitude']
|
13
|
+
puts 'Longitude: '
|
14
|
+
puts record['longitude']
|
15
|
+
puts 'ISP: ' + record['isp']
|
16
|
+
puts 'Domain: ' + record['domain']
|
17
|
+
puts 'Net Speed: ' + record['netspeed']
|
18
|
+
puts 'Area Code: ' + record['areacode']
|
19
|
+
puts 'IDD Code: ' + record['iddcode']
|
20
|
+
puts 'Time Zone: ' + record['timezone']
|
21
|
+
puts 'ZIP Code: ' + record['zipcode']
|
22
|
+
puts 'Weather Station Code: ' + record['weatherstationname']
|
23
|
+
puts 'Weather Station Name: ' + record['weatherstationcode']
|
24
|
+
puts 'MCC: ' + record['mcc']
|
25
|
+
puts 'MNC: ' + record['mnc']
|
26
|
+
puts 'Mobile Name: ' + record['mobilebrand']
|
27
|
+
puts 'Elevation: '
|
28
|
+
puts record['elevation']
|
29
|
+
puts 'Usage Type: ' + record['usagetype']
|
30
|
+
puts 'Address Type: ' + record['addresstype']
|
31
|
+
puts 'Category: ' + record['category']
|
35
32
|
|
36
33
|
i2l.close()
|
37
34
|
|
38
35
|
# Web Service
|
39
36
|
ws = Ip2locationWebService.new('demo', 'WS25', true)
|
40
37
|
record = ws.lookup('8.8.8.8', 'continent,country,region,city,geotargeting,country_groupings,time_zone_info', 'en')
|
41
|
-
|
42
|
-
|
43
|
-
|
38
|
+
puts record
|
39
|
+
puts ws.get_credit()
|
40
|
+
|
41
|
+
# IP Tools
|
42
|
+
iptool = Ip2locationIpTools.new()
|
43
|
+
puts iptool.is_ipv4('8.8.8.8')
|
44
|
+
puts iptool.is_ipv6('2001:4860:4860::8888')
|
45
|
+
puts iptool.ipv4_to_decimal('8.8.8.8')
|
46
|
+
puts iptool.decimal_to_ipv4(134744072)
|
47
|
+
puts iptool.ipv6_to_decimal('2001:4860:4860::8888')
|
48
|
+
puts iptool.decimal_to_ipv6(42541956123769884636017138956568135816)
|
49
|
+
puts iptool.ipv4_to_cidr('8.0.0.0', '8.255.255.255')
|
50
|
+
puts iptool.cidr_to_ipv4('8.0.0.0/8')
|
51
|
+
puts iptool.ipv6_to_cidr('2002:0000:0000:1234:abcd:ffff:c0a8:0000', '2002:0000:0000:1234:ffff:ffff:ffff:ffff')
|
52
|
+
puts iptool.cidr_to_ipv6('2002::1234:abcd:ffff:c0a8:101/64')
|
53
|
+
puts iptool.compress_ipv6('2002:0000:0000:1234:ffff:ffff:ffff:ffff')
|
54
|
+
puts iptool.expand_ipv6('2002::1234:ffff:ffff:ffff:ffff')
|
data/ip2location_ruby.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "ip2location_ruby"
|
3
|
-
s.version = "8.
|
3
|
+
s.version = "8.5.0"
|
4
4
|
|
5
5
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
6
6
|
s.require_paths = ["lib"]
|
@@ -31,6 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
"lib/ip2location_ruby/ip2location_record.rb",
|
32
32
|
"spec/assets/IP2LOCATION-LITE-DB1.IPV6.BIN",
|
33
33
|
"spec/ip2location_ruby_database_spec.rb",
|
34
|
+
"spec/ip2location_ruby_iptools_spec.rb",
|
34
35
|
"spec/ip2location_ruby_webservice_spec.rb",
|
35
36
|
"spec/spec_helper.rb",
|
36
37
|
"rb/data/IP2LOCATION-LITE-DB1.IPV6.BIN"
|
@@ -54,18 +55,18 @@ Gem::Specification.new do |s|
|
|
54
55
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
55
56
|
s.add_runtime_dependency(%q<bindata>, [">= 0"])
|
56
57
|
s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
|
57
|
-
s.add_development_dependency(%q<rdoc>, ["
|
58
|
+
s.add_development_dependency(%q<rdoc>, [">= 6.3.1"])
|
58
59
|
s.add_development_dependency(%q<bundler>, [">= 1.2.0"])
|
59
60
|
else
|
60
61
|
s.add_dependency(%q<bindata>, [">= 0"])
|
61
62
|
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
62
|
-
s.add_dependency(%q<rdoc>, ["
|
63
|
+
s.add_dependency(%q<rdoc>, [">= 6.3.1"])
|
63
64
|
s.add_dependency(%q<bundler>, [">= 1.2.0"])
|
64
65
|
end
|
65
66
|
else
|
66
67
|
s.add_dependency(%q<bindata>, [">= 0"])
|
67
68
|
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
68
|
-
s.add_dependency(%q<rdoc>, ["
|
69
|
+
s.add_dependency(%q<rdoc>, [">= 6.3.1"])
|
69
70
|
s.add_dependency(%q<bundler>, [">= 1.2.0"])
|
70
71
|
end
|
71
72
|
end
|
data/lib/ip2location_ruby.rb
CHANGED
@@ -13,7 +13,7 @@ require 'ip2location_ruby/ip2location_record'
|
|
13
13
|
class Ip2location
|
14
14
|
attr_accessor :record_class4, :record_class6, :v4, :file, :db_index, :count, :base_addr, :ipno, :count, :record, :database, :columns, :ip_version, :ipv4databasecount, :ipv4databaseaddr, :ipv4indexbaseaddr, :ipv6databasecount, :ipv6databaseaddr, :ipv6indexbaseaddr, :databaseyear, :databasemonth, :databaseday, :last_err_msg
|
15
15
|
|
16
|
-
VERSION = '8.
|
16
|
+
VERSION = '8.5.0'
|
17
17
|
FIELD_NOT_SUPPORTED = 'NOT SUPPORTED'
|
18
18
|
INVALID_IP_ADDRESS = 'INVALID IP ADDRESS'
|
19
19
|
INVALID_BIN_DATABASE = 'Incorrect IP2Location BIN file format. Please make sure that you are using the latest IP2Location BIN file.'
|
@@ -29,7 +29,7 @@ class Ip2location
|
|
29
29
|
self.file = File.open(File.expand_path url, 'rb')
|
30
30
|
rescue
|
31
31
|
self.last_err_msg = 'Ip2location.new.open() error in opening ' + url +'.'
|
32
|
-
abort('Ip2location.new.open() error in opening ' + url +'.')
|
32
|
+
abort('Ip2location.new.open() error in opening ' + url + '. No such file in the /your_ip2location_ruby_library_path/rb/ folder.')
|
33
33
|
else
|
34
34
|
end
|
35
35
|
i2l = Ip2locationConfig.read(file)
|
@@ -88,7 +88,7 @@ class Ip2location
|
|
88
88
|
if ip_version == 6 && self.ipv6databasecount == 0
|
89
89
|
return IPV6_ADDRESS_IN_IPV4_BIN
|
90
90
|
end
|
91
|
-
col_length = columns * 4
|
91
|
+
col_length = self.columns * 4
|
92
92
|
if ipv4indexbaseaddr > 0 || ipv6indexbaseaddr > 0
|
93
93
|
indexpos = 0
|
94
94
|
case ip_version
|
@@ -107,8 +107,7 @@ class Ip2location
|
|
107
107
|
ipnum = realipno - 1
|
108
108
|
end
|
109
109
|
end
|
110
|
-
low =
|
111
|
-
high = read32(indexpos + 4)
|
110
|
+
low, high = read32x2(indexpos)
|
112
111
|
return self.record = bsearch(low, high, ipnum, self.base_addr, col_length)
|
113
112
|
else
|
114
113
|
return self.record = bsearch(0, self.count, ipnum, self.base_addr, col_length)
|
@@ -618,7 +617,7 @@ class Ip2location
|
|
618
617
|
mid = (low + high) >> 1
|
619
618
|
ip_from, ip_to = get_from_to(mid, base_addr, col_length)
|
620
619
|
if ipnum >= ip_from && ipnum < ip_to
|
621
|
-
from_base = (
|
620
|
+
from_base = (base_addr + mid * (col_length + (self.v4 ? 0 : 12)))
|
622
621
|
file.seek(from_base)
|
623
622
|
if v4
|
624
623
|
return self.record_class4.read(file)
|
@@ -636,11 +635,12 @@ class Ip2location
|
|
636
635
|
end
|
637
636
|
|
638
637
|
def get_from_to(mid, base_addr, col_length)
|
639
|
-
from_base = (
|
638
|
+
from_base = (base_addr + mid * (col_length + (v4 ? 0 : 12)))
|
639
|
+
data_length = col_length + (v4 ? 4 : (12 + 16))
|
640
640
|
file.seek(from_base)
|
641
|
-
|
642
|
-
|
643
|
-
ip_to = v4 ?
|
641
|
+
data_read = file.read(data_length)
|
642
|
+
ip_from = v4 ? data_read[0..3].unpack('V').first : readipv6(data_read[0..15].unpack('V*'))
|
643
|
+
ip_to = v4 ? data_read[(data_length - 4)..(data_length - 1)].unpack('V').first : readipv6(data_read[(data_length - 16)..(data_length - 1)].unpack('V*'))
|
644
644
|
[ip_from, ip_to]
|
645
645
|
end
|
646
646
|
|
@@ -651,7 +651,7 @@ class Ip2location
|
|
651
651
|
else
|
652
652
|
ipv = 6
|
653
653
|
ipnum = ip.to_i + 0
|
654
|
-
#reformat ipv4 address in ipv6
|
654
|
+
#reformat ipv4 address in ipv6
|
655
655
|
if ipnum >= 281470681743360 && ipnum <= 281474976710655
|
656
656
|
ipv = 4
|
657
657
|
ipnum = ipnum - 281470681743360
|
@@ -676,17 +676,19 @@ class Ip2location
|
|
676
676
|
[ipv, ipnum]
|
677
677
|
end
|
678
678
|
|
679
|
-
def
|
679
|
+
def read32x2(indexp)
|
680
680
|
file.seek(indexp - 1)
|
681
|
-
|
681
|
+
data_read = file.read(8)
|
682
|
+
data1 = data_read[0..3].unpack('V').first
|
683
|
+
data2 = data_read[4..7].unpack('V').first
|
684
|
+
return [data1, data2]
|
682
685
|
end
|
683
686
|
|
684
|
-
def readipv6(
|
685
|
-
parts = filer.read(16).unpack('V*')
|
687
|
+
def readipv6(parts)
|
686
688
|
return parts[0] + parts[1] * 4294967296 + parts[2] * 4294967296**2 + parts[3] * 4294967296**3
|
687
689
|
end
|
688
690
|
|
689
|
-
private :get_record, :bsearch, :get_from_to, :
|
691
|
+
private :get_record, :bsearch, :get_from_to, :read32x2, :readipv6
|
690
692
|
end
|
691
693
|
|
692
694
|
class Ip2locationWebService
|
@@ -717,7 +719,7 @@ class Ip2locationWebService
|
|
717
719
|
if parsed_response.nil?
|
718
720
|
return false
|
719
721
|
end
|
720
|
-
if
|
722
|
+
if parsed_response["country_code"].nil?
|
721
723
|
raise Exception.new "Error: " + parsed_response["response"]
|
722
724
|
end
|
723
725
|
return parsed_response
|
@@ -738,4 +740,228 @@ class Ip2locationWebService
|
|
738
740
|
end
|
739
741
|
return parsed_response["response"]
|
740
742
|
end
|
743
|
+
end
|
744
|
+
|
745
|
+
class Ip2locationIpTools
|
746
|
+
def is_ipv4(ip)
|
747
|
+
if !(IPAddr.new(ip) rescue nil).nil?
|
748
|
+
if IPAddr.new(ip).ipv4?
|
749
|
+
return true
|
750
|
+
else
|
751
|
+
return false
|
752
|
+
end
|
753
|
+
else
|
754
|
+
return false
|
755
|
+
end
|
756
|
+
end
|
757
|
+
|
758
|
+
def is_ipv6(ip)
|
759
|
+
if !(IPAddr.new(ip) rescue nil).nil?
|
760
|
+
if IPAddr.new(ip).ipv6?
|
761
|
+
return true
|
762
|
+
else
|
763
|
+
return false
|
764
|
+
end
|
765
|
+
else
|
766
|
+
return false
|
767
|
+
end
|
768
|
+
end
|
769
|
+
|
770
|
+
def ipv4_to_decimal(ip)
|
771
|
+
if !(IPAddr.new(ip) rescue nil).nil?
|
772
|
+
ip = IPAddr.new(ip)
|
773
|
+
if ip.ipv4?
|
774
|
+
return ip.to_i
|
775
|
+
else
|
776
|
+
return
|
777
|
+
end
|
778
|
+
else
|
779
|
+
return
|
780
|
+
end
|
781
|
+
end
|
782
|
+
|
783
|
+
def decimal_to_ipv4(number)
|
784
|
+
if number.is_a? Numeric
|
785
|
+
return IPAddr.new(number, Socket::AF_INET).to_s
|
786
|
+
else
|
787
|
+
return
|
788
|
+
end
|
789
|
+
end
|
790
|
+
|
791
|
+
def ipv6_to_decimal(ip)
|
792
|
+
if !(IPAddr.new(ip) rescue nil).nil?
|
793
|
+
ip = IPAddr.new(ip)
|
794
|
+
if ip.ipv6?
|
795
|
+
return ip.to_i
|
796
|
+
else
|
797
|
+
return
|
798
|
+
end
|
799
|
+
else
|
800
|
+
return
|
801
|
+
end
|
802
|
+
end
|
803
|
+
|
804
|
+
def decimal_to_ipv6(number)
|
805
|
+
if number.is_a? Numeric
|
806
|
+
return IPAddr.new(number, Socket::AF_INET6).to_s
|
807
|
+
else
|
808
|
+
return
|
809
|
+
end
|
810
|
+
end
|
811
|
+
|
812
|
+
def ipv4_to_cidr(ipfrom, ipto)
|
813
|
+
if (!(IPAddr.new(ipfrom) rescue nil).nil?) and (!(IPAddr.new(ipto) rescue nil).nil?)
|
814
|
+
ipfrom = IPAddr.new(ipfrom)
|
815
|
+
ipto = IPAddr.new(ipto)
|
816
|
+
if ipfrom.ipv4? and ipto.ipv4?
|
817
|
+
ipfrom = ipfrom.to_i
|
818
|
+
ipto = ipto.to_i
|
819
|
+
result = []
|
820
|
+
while ipto >= ipfrom do
|
821
|
+
maxSize = 32
|
822
|
+
while maxSize > 0 do
|
823
|
+
mask = (2**32 - 2**(32-(maxSize - 1)))
|
824
|
+
maskBase = ipfrom & mask
|
825
|
+
if maskBase != ipfrom
|
826
|
+
break
|
827
|
+
end
|
828
|
+
maxSize-=1
|
829
|
+
end
|
830
|
+
x = Math.log(ipto - ipfrom + 1)/Math.log(2)
|
831
|
+
maxDiff = (32 - x.floor).floor
|
832
|
+
|
833
|
+
if maxSize < maxDiff
|
834
|
+
maxSize = maxDiff
|
835
|
+
end
|
836
|
+
|
837
|
+
ip = IPAddr.new(ipfrom, Socket::AF_INET).to_s
|
838
|
+
cidr = [ip, maxSize].join('/')
|
839
|
+
result.push cidr
|
840
|
+
ipfrom += 2**(32-maxSize)
|
841
|
+
end
|
842
|
+
return result
|
843
|
+
else
|
844
|
+
return
|
845
|
+
end
|
846
|
+
else
|
847
|
+
return
|
848
|
+
end
|
849
|
+
end
|
850
|
+
|
851
|
+
def cidr_to_ipv4(cidr)
|
852
|
+
if cidr.include? "/"
|
853
|
+
cidr = IPAddr.new(cidr)
|
854
|
+
arr_tmp = cidr.to_range.to_s.split('..')
|
855
|
+
ip_arr = {}
|
856
|
+
ip_arr['ip_start'] = arr_tmp[0]
|
857
|
+
ip_arr['ip_end'] = arr_tmp[1]
|
858
|
+
return ip_arr
|
859
|
+
else
|
860
|
+
return
|
861
|
+
end
|
862
|
+
end
|
863
|
+
|
864
|
+
def ipv6_to_cidr(ipfrom_ori, ipto)
|
865
|
+
if (!(IPAddr.new(ipfrom_ori) rescue nil).nil?) and (!(IPAddr.new(ipto) rescue nil).nil?)
|
866
|
+
ipfrom = IPAddr.new(ipfrom_ori)
|
867
|
+
ipto = IPAddr.new(ipto)
|
868
|
+
if ipfrom.ipv6? and ipto.ipv6?
|
869
|
+
ipfrom = '00' + ipfrom.to_i.to_s(2)
|
870
|
+
ipto = '00' + ipto.to_i.to_s(2)
|
871
|
+
result = []
|
872
|
+
if ipfrom == ipto
|
873
|
+
cidr = ipfrom_ori + '/128'
|
874
|
+
result.push cidr
|
875
|
+
return result
|
876
|
+
end
|
877
|
+
if ipfrom > ipto
|
878
|
+
ipfrom, ipto = ipto, ipfrom
|
879
|
+
end
|
880
|
+
networks = {}
|
881
|
+
network_size = 0
|
882
|
+
while ipto > ipfrom do
|
883
|
+
if ipfrom[-1, 1] == '1'
|
884
|
+
networks[ipfrom[network_size, (128 - network_size)] + ('0' * network_size)] = 128 - network_size
|
885
|
+
n = ipfrom.rindex('0')
|
886
|
+
ipfrom = ((n == 0) ? '' : ipfrom[0, n]) + '1' + ('0' * (128 - n - 1))
|
887
|
+
end
|
888
|
+
|
889
|
+
if ipto[-1, 1] == '0'
|
890
|
+
networks[ipto[network_size, (128 - network_size)] + ('0' * network_size)] = 128 - network_size
|
891
|
+
n = ipto.rindex('1')
|
892
|
+
ipto = ((n == 0) ? '' : ipto[0, n]) + '0' + ('1' * (128 - n - 1))
|
893
|
+
end
|
894
|
+
|
895
|
+
if ipfrom > ipto
|
896
|
+
next
|
897
|
+
end
|
898
|
+
|
899
|
+
shift = 128 - [ipfrom.rindex('0'), ipto.rindex('1')].max
|
900
|
+
ipfrom = ('0' * shift) + ipfrom[0, (128 - shift)]
|
901
|
+
ipto = ('0' * shift) + ipto[0, (128 - shift)]
|
902
|
+
network_size = network_size + shift
|
903
|
+
|
904
|
+
if ipfrom == ipto
|
905
|
+
networks[ipfrom[network_size, (128 - network_size)] + ('0' * network_size)] = 128 - network_size
|
906
|
+
next
|
907
|
+
end
|
908
|
+
end
|
909
|
+
|
910
|
+
networks.each do |ip, netmask|
|
911
|
+
result.push IPAddr.new(ip.to_i(2), Socket::AF_INET6).to_s + '/' + netmask.to_s
|
912
|
+
end
|
913
|
+
return result
|
914
|
+
else
|
915
|
+
return
|
916
|
+
end
|
917
|
+
else
|
918
|
+
return
|
919
|
+
end
|
920
|
+
end
|
921
|
+
|
922
|
+
def cidr_to_ipv6(cidr)
|
923
|
+
if cidr.include? "/"
|
924
|
+
ip_start = IPAddr.new(cidr.to_s.split('/').first).to_i.to_s(16).scan(/.{4}/)
|
925
|
+
ip_start = ip_start[0] + ':' + ip_start[1] + ':' + ip_start[2] + ':' + ip_start[3] + ':' + ip_start[4] + ':' + ip_start[5] + ':' + ip_start[6] + ':' + ip_start[7]
|
926
|
+
|
927
|
+
cidr_new = IPAddr.new(cidr)
|
928
|
+
arr_tmp = cidr_new.to_range.to_s.split('..')
|
929
|
+
ip_end = IPAddr.new(arr_tmp[1]).to_i.to_s(16).scan(/.{4}/)
|
930
|
+
ip_end = ip_end[0] + ':' + ip_end[1] + ':' + ip_end[2] + ':' + ip_end[3] + ':' + ip_end[4] + ':' + ip_end[5] + ':' + ip_end[6] + ':' + ip_end[7]
|
931
|
+
|
932
|
+
ip_arr = {}
|
933
|
+
ip_arr['ip_start'] = ip_start
|
934
|
+
ip_arr['ip_end'] = ip_end
|
935
|
+
return ip_arr
|
936
|
+
else
|
937
|
+
return
|
938
|
+
end
|
939
|
+
end
|
940
|
+
|
941
|
+
def compress_ipv6(ip)
|
942
|
+
if !(IPAddr.new(ip) rescue nil).nil?
|
943
|
+
ip = IPAddr.new(ip)
|
944
|
+
if ip.ipv6?
|
945
|
+
return ip
|
946
|
+
else
|
947
|
+
return
|
948
|
+
end
|
949
|
+
else
|
950
|
+
return
|
951
|
+
end
|
952
|
+
end
|
953
|
+
|
954
|
+
def expand_ipv6(ip)
|
955
|
+
if !(IPAddr.new(ip) rescue nil).nil?
|
956
|
+
ip = IPAddr.new(ip)
|
957
|
+
if ip.ipv6?
|
958
|
+
res = ip.to_i.to_s(16).scan(/.{4}/)
|
959
|
+
return res[0] + ':' + res[1] + ':' + res[2] + ':' + res[3] + ':' + res[4] + ':' + res[5] + ':' + res[6] + ':' + res[7]
|
960
|
+
else
|
961
|
+
return
|
962
|
+
end
|
963
|
+
else
|
964
|
+
return
|
965
|
+
end
|
966
|
+
end
|
741
967
|
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Ip2location" do
|
4
|
+
it "work correctly with iptools is_ipv4" do
|
5
|
+
iptool = Ip2locationIpTools.new()
|
6
|
+
record = iptool.is_ipv4('8.8.8.8')
|
7
|
+
expect(record).to eq true
|
8
|
+
end
|
9
|
+
|
10
|
+
it "work correctly with iptools invalid is_ipv4" do
|
11
|
+
iptool = Ip2locationIpTools.new()
|
12
|
+
record = iptool.is_ipv4('8.8.8.555')
|
13
|
+
expect(record).to eq false
|
14
|
+
end
|
15
|
+
|
16
|
+
it "work correctly with iptools is_ipv6" do
|
17
|
+
iptool = Ip2locationIpTools.new()
|
18
|
+
record = iptool.is_ipv6('2001:4860:4860::8888')
|
19
|
+
expect(record).to eq true
|
20
|
+
end
|
21
|
+
|
22
|
+
it "work correctly with iptools invalid is_ipv6" do
|
23
|
+
iptool = Ip2locationIpTools.new()
|
24
|
+
record = iptool.is_ipv6('2001:4860:4860::ZZZZ')
|
25
|
+
expect(record).to eq false
|
26
|
+
end
|
27
|
+
|
28
|
+
it "work correctly with iptools ipv4_to_decimal" do
|
29
|
+
iptool = Ip2locationIpTools.new()
|
30
|
+
record = iptool.ipv4_to_decimal('8.8.8.8')
|
31
|
+
expect(record).to eq 134744072
|
32
|
+
end
|
33
|
+
|
34
|
+
it "work correctly with iptools decimal_to_ipv4" do
|
35
|
+
iptool = Ip2locationIpTools.new()
|
36
|
+
record = iptool.decimal_to_ipv4(134744072)
|
37
|
+
expect(record).to eq '8.8.8.8'
|
38
|
+
end
|
39
|
+
|
40
|
+
it "work correctly with iptools ipv6_to_decimal" do
|
41
|
+
iptool = Ip2locationIpTools.new()
|
42
|
+
record = iptool.ipv6_to_decimal('2001:4860:4860::8888')
|
43
|
+
expect(record).to eq 42541956123769884636017138956568135816
|
44
|
+
end
|
45
|
+
|
46
|
+
it "work correctly with iptools decimal_to_ipv6" do
|
47
|
+
iptool = Ip2locationIpTools.new()
|
48
|
+
record = iptool.decimal_to_ipv6(42541956123769884636017138956568135816)
|
49
|
+
expect(record).to eq '2001:4860:4860::8888'
|
50
|
+
end
|
51
|
+
|
52
|
+
it "work correctly with iptools ipv4_to_cidr" do
|
53
|
+
iptool = Ip2locationIpTools.new()
|
54
|
+
record = iptool.ipv4_to_cidr('8.0.0.0', '8.255.255.255')
|
55
|
+
expect(record).to eq ['8.0.0.0/8']
|
56
|
+
end
|
57
|
+
|
58
|
+
it "work correctly with iptools cidr_to_ipv4" do
|
59
|
+
iptool = Ip2locationIpTools.new()
|
60
|
+
record = iptool.cidr_to_ipv4('8.0.0.0/8')
|
61
|
+
expect(record).to include(
|
62
|
+
"ip_start"=>"8.0.0.0",
|
63
|
+
"ip_end"=>"8.255.255.255"
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "work correctly with iptools ipv6_to_cidr" do
|
68
|
+
iptool = Ip2locationIpTools.new()
|
69
|
+
record = iptool.ipv6_to_cidr('2002:0000:0000:1234:abcd:ffff:c0a8:0000', '2002:0000:0000:1234:ffff:ffff:ffff:ffff')
|
70
|
+
expect(record).to eq ['2002::1234:abcd:ffff:c0a8:0/109','2002::1234:abcd:ffff:c0b0:0/108','2002::1234:abcd:ffff:c0c0:0/106','2002::1234:abcd:ffff:c100:0/104','2002::1234:abcd:ffff:c200:0/103','2002::1234:abcd:ffff:c400:0/102','2002::1234:abcd:ffff:c800:0/101','2002::1234:abcd:ffff:d000:0/100','2002::1234:abcd:ffff:e000:0/99','2002:0:0:1234:abce::/79','2002:0:0:1234:abd0::/76','2002:0:0:1234:abe0::/75','2002:0:0:1234:ac00::/70','2002:0:0:1234:b000::/68','2002:0:0:1234:c000::/66']
|
71
|
+
end
|
72
|
+
|
73
|
+
it "work correctly with iptools cidr_to_ipv6" do
|
74
|
+
iptool = Ip2locationIpTools.new()
|
75
|
+
record = iptool.cidr_to_ipv6('2002::1234:abcd:ffff:c0a8:101/64')
|
76
|
+
expect(record).to include(
|
77
|
+
"ip_start"=>"2002:0000:0000:1234:abcd:ffff:c0a8:0101",
|
78
|
+
"ip_end"=>"2002:0000:0000:1234:ffff:ffff:ffff:ffff"
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "work correctly with iptools compress_ipv6" do
|
83
|
+
iptool = Ip2locationIpTools.new()
|
84
|
+
record = iptool.compress_ipv6('2002:0000:0000:1234:ffff:ffff:ffff:ffff')
|
85
|
+
expect(record).to eq '2002::1234:ffff:ffff:ffff:ffff'
|
86
|
+
end
|
87
|
+
|
88
|
+
it "work correctly with iptools expand_ipv6" do
|
89
|
+
iptool = Ip2locationIpTools.new()
|
90
|
+
record = iptool.expand_ipv6('2002::1234:ffff:ffff:ffff:ffff')
|
91
|
+
expect(record).to eq '2002:0000:0000:1234:ffff:ffff:ffff:ffff'
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ip2location_ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 8.
|
4
|
+
version: 8.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ip2location
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-06-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bindata
|
@@ -42,16 +42,16 @@ dependencies:
|
|
42
42
|
name: rdoc
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 6.3.1
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 6.3.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -97,6 +97,7 @@ files:
|
|
97
97
|
- rb/data/IP2LOCATION-LITE-DB1.IPV6.BIN
|
98
98
|
- spec/assets/IP2LOCATION-LITE-DB1.IPV6.BIN
|
99
99
|
- spec/ip2location_ruby_database_spec.rb
|
100
|
+
- spec/ip2location_ruby_iptools_spec.rb
|
100
101
|
- spec/ip2location_ruby_webservice_spec.rb
|
101
102
|
- spec/spec_helper.rb
|
102
103
|
homepage: https://github.com/ip2location/ip2location-ruby
|
@@ -107,7 +108,7 @@ metadata:
|
|
107
108
|
documentation_uri: https://www.rubydoc.info/gems/ip2location_ruby
|
108
109
|
homepage_uri: https://www.ip2location.com
|
109
110
|
source_code_uri: https://github.com/ip2location/ip2location-ruby
|
110
|
-
post_install_message:
|
111
|
+
post_install_message:
|
111
112
|
rdoc_options: []
|
112
113
|
require_paths:
|
113
114
|
- lib
|
@@ -122,9 +123,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
123
|
- !ruby/object:Gem::Version
|
123
124
|
version: '0'
|
124
125
|
requirements: []
|
125
|
-
|
126
|
-
|
127
|
-
signing_key:
|
126
|
+
rubygems_version: 3.2.33
|
127
|
+
signing_key:
|
128
128
|
specification_version: 4
|
129
129
|
summary: the ip2location ruby library
|
130
130
|
test_files: []
|