pwnedkeys-filter 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 76391e2ba3bc336b7c1eae6034f034b3fce4bbf01094aa96c3bd76c71d5c9f0e
4
- data.tar.gz: 1a84b07456594a252fd720c9a6152452a89403f5b54c337c4b768d44653b0961
3
+ metadata.gz: 9b916d185473c8a9bb1a2cc28036121d7c015af4abc287a4cc778f91d8184ea5
4
+ data.tar.gz: 3622ef85be404de370844c1fcede849a43e536d4c8261d43285ad45cc5d7ded4
5
5
  SHA512:
6
- metadata.gz: 1e94333e88347be45babe142ceab68301c1897e7f998d0d1cbaa05a9cf9d93eac5cf3e51b363d089f894071793d8bf2309ee30c91d221991e04346a3906a882b
7
- data.tar.gz: ff38e9a11c06de9cf9fb8aa5073010b03d986e33ec58e6d29d77677f3cb34015c386c175dc03f3f015cdeb331999dea42cb7c068184b39be47358b06bcdc3c7a
6
+ metadata.gz: e5a97277a35b9f2dd1901ab599bd3de39954c8bfceb868f3c33a3b275bc7390d2bb81a988d660d5f88d6cb5caf8043cacc830b02ebf14d4cb6d5d92094dce64a
7
+ data.tar.gz: 9d1ee32b9cec58d5d235aa569192ddbd7fecff7db735217d925d2b9ddbaf46d99e0766388300110227edb7e3f5c8dd25f575ccc20654615020cd8e534b783ab5
@@ -117,6 +117,53 @@ module Pwnedkeys
117
117
  nil
118
118
  end
119
119
 
120
+ # Calculate count/length parameters for a given entry count and desired false-positive rate.
121
+ #
122
+ # @param entries [Integer] how many elements the bloom filter should
123
+ # accommodate.
124
+ #
125
+ # @param fp_rate [Float] the maximum false-positive rate you wish to
126
+ # accept.
127
+ #
128
+ # @return [Hash<Symbol, Integer>] the `:hash_count` and `:hash_length` which
129
+ # will produce the desired false-positive rate if the filter is filled
130
+ # with the specified number of entries.
131
+ #
132
+ def self.filter_parameters(entries:, fp_rate:)
133
+ # Blessings unto https://en.wikipedia.org/wiki/Bloom_filter#Optimal_number_of_hash_functions
134
+ optimal_filter_bits = (-1 * entries * Math.log(fp_rate) / Math.log(2) / Math.log(2))
135
+ hash_length = (Math.log2(optimal_filter_bits)).ceil
136
+ actual_filter_bits = 2 ** hash_length
137
+
138
+ # We could, in theory, just use the "optimal k" (hash count), which would
139
+ # often produce an actual false-positive rate much smaller than our
140
+ # target (because actual_filter_bits can be *significantly* larger than
141
+ # optimal_filter_bits). Instead, to minimise the hashing required, we
142
+ # can use the extra filter length available to choose a smaller k that
143
+ # still satisfies the target false positive rate.
144
+ #
145
+ # Because my algebra isn't up to solving the FP rate equation for k, and
146
+ # because the search space of possible values of k is small and bounded
147
+ # (by 1, and by the "optimal k" on the upper bound), brute-forcing things
148
+ # seems the easiest option.
149
+
150
+ upper_bound = (Math.log(2) * actual_filter_bits / entries).ceil
151
+ hash_count = (1..upper_bound).find do |k|
152
+ (1 - (1 - 1.0 / actual_filter_bits) ** (k * entries)) ** k < fp_rate
153
+ end
154
+
155
+ if hash_count.nil?
156
+ #:nocov:
157
+ raise RuntimeError, "CAN'T HAPPEN: Could not determine hash_count for entries: #{entries}, fp_rate: #{fp_rate}. Please report a violation of the laws of mathematics."
158
+ #:nocov:
159
+ end
160
+
161
+ {
162
+ hash_count: hash_count,
163
+ hash_length: hash_length,
164
+ }
165
+ end
166
+
120
167
  # Open an existing pwnedkeys bloom filter data file.
121
168
  #
122
169
  # @param filename [String] the file to open.
@@ -245,7 +292,6 @@ module Pwnedkeys
245
292
  (1 - (1 - 1.0 / filter_bit_count) ** (hash_count * entry_count)) ** hash_count
246
293
  end
247
294
 
248
-
249
295
  private
250
296
 
251
297
  def hash_count
@@ -29,7 +29,6 @@ Gem::Specification.new do |s|
29
29
  s.add_development_dependency 'github-release'
30
30
  s.add_development_dependency 'git-version-bump'
31
31
  s.add_development_dependency 'guard-rspec'
32
- s.add_development_dependency 'rack-test'
33
32
  s.add_development_dependency 'rake', "~> 12.0"
34
33
  s.add_development_dependency 'redcarpet'
35
34
  s.add_development_dependency 'rspec'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pwnedkeys-filter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Palmer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-21 00:00:00.000000000 Z
11
+ date: 2020-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: openssl-additions
@@ -94,20 +94,6 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: rack-test
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: rake
113
99
  requirement: !ruby/object:Gem::Requirement
@@ -209,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
209
195
  - !ruby/object:Gem::Version
210
196
  version: '0'
211
197
  requirements: []
212
- rubygems_version: 3.0.1
198
+ rubygems_version: 3.0.3
213
199
  signing_key:
214
200
  specification_version: 4
215
201
  summary: Library to query pwnedkeys.com bloom filters