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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88ca0a0eeda11477542ff26e73d650ee4710fe53cefacfae2becdab77a60b296
4
- data.tar.gz: b53da2a74fb4cbe4580d0745cee0b9be50b21dc45d63b7baf4fd2d94090380a6
3
+ metadata.gz: f7f7cc867aa07b3595ae89b5f5fa55fab2b210236b106fa8ad10ccb5b9dd15b1
4
+ data.tar.gz: 36b720b84b89cfaad323c1d695e1b5408eca69476197cdb7911cdb614856c5e9
5
5
  SHA512:
6
- metadata.gz: f20f7d2bb1fd83dacaacc4f78e9f2641a67be6a833be040c9ceaf289471d58658df35f01623bb8429bfaf9830df36e10517a693ab564c4542911c510f5b90292
7
- data.tar.gz: b8f9340cd456e71a2e7920290f04aeea7d1d88692d53dee247f537f31b7ab25e5ccf83870667b5df626080c65a60c872ede67c606aab11dcdeef1d2cc7c5c4dd
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.12.2)
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 (~> 3.12)
24
+ rdoc (>= 6.3.1)
25
25
  rspec (~> 2.8.0)
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2021 IP2Location ( support@ip2location.com )
1
+ Copyright (c) 2022 IP2Location ( support@ip2location.com )
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
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
- | category | Returns the IAB content taxonomy category of IP address or domain name. |
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.3.1
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
- print 'Country Code: ' + record['country_short'] + "\n"
8
- print 'Country Name: ' + record['country_long'] + "\n"
9
- print 'Region Name: ' + record['region'] + "\n"
10
- print 'City Name: ' + record['city'] + "\n"
11
- print 'Latitude: '
12
- print record['latitude']
13
- print "\n"
14
- print 'Longitude: '
15
- print record['longitude']
16
- print "\n"
17
- print 'ISP: ' + record['isp'] + "\n"
18
- print 'Domain: ' + record['domain'] + "\n"
19
- print 'Net Speed: ' + record['netspeed'] + "\n"
20
- print 'Area Code: ' + record['areacode'] + "\n"
21
- print 'IDD Code: ' + record['iddcode'] + "\n"
22
- print 'Time Zone: ' + record['timezone'] + "\n"
23
- print 'ZIP Code: ' + record['zipcode'] + "\n"
24
- print 'Weather Station Code: ' + record['weatherstationname'] + "\n"
25
- print 'Weather Station Name: ' + record['weatherstationcode'] + "\n"
26
- print 'MCC: ' + record['mcc'] + "\n"
27
- print 'MNC: ' + record['mnc'] + "\n"
28
- print 'Mobile Name: ' + record['mobilebrand'] + "\n"
29
- print 'Elevation: '
30
- print record['elevation']
31
- print "\n"
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
- print record
42
- print "\n"
43
- print ws.get_credit()
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')
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "ip2location_ruby"
3
- s.version = "8.3.1"
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>, ["~> 3.12"])
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>, ["~> 3.12"])
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>, ["~> 3.12"])
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
@@ -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.3.1'
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 = read32(indexpos)
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 = ( base_addr + mid * (col_length + (self.v4 ? 0 : 12)))
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 = ( base_addr + mid * (col_length + (v4 ? 0 : 12)))
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
- ip_from = v4 ? file.read(4).unpack('V').first : readipv6(file)
642
- file.seek(from_base + col_length + (v4 ? 0 : 12))
643
- ip_to = v4 ? file.read(4).unpack('V').first : readipv6(file)
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 read32(indexp)
679
+ def read32x2(indexp)
680
680
  file.seek(indexp - 1)
681
- return file.read(4).unpack('V').first
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(filer)
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, :read32, :readipv6
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 !parsed_response["response"].nil?
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
@@ -10,6 +10,6 @@ describe "Ip2location" do
10
10
  it "work correctly with web service get_credit" do
11
11
  ws = Ip2locationWebService.new('demo', 'WS25', true)
12
12
  record = ws.get_credit()
13
- expect(record).to_not eq 0
13
+ expect(record).to eq 0
14
14
  end
15
15
  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.3.1
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: 2021-07-14 00:00:00.000000000 Z
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: '3.12'
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: '3.12'
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
- rubyforge_project:
126
- rubygems_version: 2.7.6.2
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: []