ip2location_ruby 8.3.1 → 8.5.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 +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: []
|