cipher_bureau 0.2.1
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.
- data/MIT-LICENSE +20 -0
- data/README.md +160 -0
- data/Rakefile +38 -0
- data/db/seeds/norwegian/wordloader.rb +47 -0
- data/lib/cipher_bureau.rb +59 -0
- data/lib/cipher_bureau/data_loader.rb +65 -0
- data/lib/cipher_bureau/dictionary.rb +63 -0
- data/lib/cipher_bureau/exceptions.rb +25 -0
- data/lib/cipher_bureau/password.rb +114 -0
- data/lib/cipher_bureau/password_meter.rb +183 -0
- data/lib/cipher_bureau/statistic.rb +48 -0
- data/lib/cipher_bureau/version.rb +3 -0
- data/lib/generators/cipher_bureau/create_migration_generator.rb +40 -0
- data/lib/generators/cipher_bureau/load_data_generator.rb +36 -0
- data/lib/generators/templates/create_cipher_bureau_dictionaries.rb +41 -0
- data/lib/generators/templates/create_cipher_bureau_statistics.rb +39 -0
- data/lib/tasks/cipher_bureau_tasks.rake +40 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/db/migrate/201301290819401_create_cipher_bureau_dictionaries.rb +19 -0
- data/test/dummy/db/migrate/201301290819402_create_cipher_bureau_statistics.rb +17 -0
- data/test/dummy/db/schema.rb +46 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/fixtures/cipher_bureau_dictionaries.yml +704 -0
- data/test/fixtures/cipher_bureau_statistics.yml +40 -0
- data/test/test_helper.rb +15 -0
- data/test/units/cipher_bureau/dictionary_test.rb +74 -0
- data/test/units/cipher_bureau/password_meter_test.rb +128 -0
- data/test/units/cipher_bureau/password_test.rb +188 -0
- data/test/units/cipher_bureau/statistic_test.rb +78 -0
- data/test/units/cipher_bureau_test.rb +45 -0
- metadata +197 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2012 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
# CipherBureau
|
2
|
+
|
3
|
+
### CipherBureau is a simple gem for password generation
|
4
|
+
|
5
|
+
Sometimes you need to generate passwords in your application.
|
6
|
+
This gem does exactly that. It also has the ability to measure the strength of passwords.
|
7
|
+
In addition it contains a dictionary for creating ```memorable``` passwords. Currently the dictionary is only in Norwegian, but you can easily load dictionaries yourself. See separate explanation on how to load dictionaries, setting up defaults etc.
|
8
|
+
|
9
|
+
|
10
|
+
# Install and Setup
|
11
|
+
|
12
|
+
Install the gem
|
13
|
+
|
14
|
+
gem install cipher_bureau
|
15
|
+
|
16
|
+
Or, in your Gemfile
|
17
|
+
|
18
|
+
gem 'cipher_bureau'
|
19
|
+
|
20
|
+
|
21
|
+
## Generating migration and loading dictionary
|
22
|
+
|
23
|
+
If you want to use the ```memorable method```, you will need to create a couple of tables for holding the dictionary.
|
24
|
+
CipherBureau includes two generators, one for generating the migration, and one for loading the dictionary.
|
25
|
+
|
26
|
+
Generate the migration:
|
27
|
+
|
28
|
+
rails generate cipher_bureau:create_migration
|
29
|
+
|
30
|
+
Load the data
|
31
|
+
|
32
|
+
rails generate cipher_bureau:load_data
|
33
|
+
|
34
|
+
Loading the data will take some time as there are more than 600,000 words, including grammar and names.
|
35
|
+
|
36
|
+
# Using the password interface
|
37
|
+
|
38
|
+
## Basic interface
|
39
|
+
|
40
|
+
Generate a password, using random as an example
|
41
|
+
|
42
|
+
```Ruby
|
43
|
+
# Generate a single random password with length 10 characters
|
44
|
+
CipherBureau::Password.random(:length => 10)
|
45
|
+
=> "ZnipfcIByq"
|
46
|
+
|
47
|
+
# Generate two random passwords with length 10 characters
|
48
|
+
CipherBureau::Password.random(2, :length => 10)
|
49
|
+
=> ["4X^gb1}oLP", "g%JJJ:Y`O."]
|
50
|
+
|
51
|
+
# Generate a random password and measure its strength
|
52
|
+
CipherBureau::Password.random(:length => 10, :strength => true)
|
53
|
+
=> ["]KF|O4vANP", 90]
|
54
|
+
|
55
|
+
# Generate two random passwords and measure their strength
|
56
|
+
CipherBureau::Password.random(2, :length => 10, :strength => true)
|
57
|
+
=> [[")1^flZvQ^4", 100], ["^DGAf83B`s", 98]]
|
58
|
+
```
|
59
|
+
|
60
|
+
## Configuring default password length
|
61
|
+
|
62
|
+
If you want you can configure the default password length
|
63
|
+
|
64
|
+
```Ruby
|
65
|
+
# Set deault length to 10 characters
|
66
|
+
CipherBureau.password_length = 10
|
67
|
+
```
|
68
|
+
|
69
|
+
## Basic methods
|
70
|
+
|
71
|
+
### Password generation methods
|
72
|
+
|
73
|
+
You can use the same parameters for all password functions, except memorable which takes more parameters
|
74
|
+
|
75
|
+
```Ruby
|
76
|
+
CipherBureau::Password.random
|
77
|
+
=> "dv$w1eD<5T"
|
78
|
+
|
79
|
+
CipherBureau::Password.letters_and_numbers
|
80
|
+
=> "qoQIfSrElc"
|
81
|
+
|
82
|
+
CipherBureau::Password.numbers_only
|
83
|
+
=> "6924908575"
|
84
|
+
|
85
|
+
CipherBureau::Password.symbols_and_numbers
|
86
|
+
=> "<~%2`!-452"
|
87
|
+
|
88
|
+
CipherBureau::Password.memorable
|
89
|
+
=> "acti)}flik"
|
90
|
+
```
|
91
|
+
|
92
|
+
The memorable password emphasize on generating passwords with symbols and numbers in the middle, as this ranks higher in security.
|
93
|
+
|
94
|
+
The memorable method accepts more arguments:
|
95
|
+
|
96
|
+
* ```:country_code``` - a numerical value of country_code, e.g. Norway 47
|
97
|
+
* ```:ascii``` - true of false. Use false to get words outside 7-bits range, such as nordic characters
|
98
|
+
* ```:camelize``` - true. Only names has first letter capitalized
|
99
|
+
* ```:grammar``` - legal values are: 'adjective','adverb','conjunction','determiner','interjection','name','noun',
|
100
|
+
'musical','numeral','preposition','pronoun','subjunctive','verb','verbalsubst',
|
101
|
+
* ```:name_tupe``` - if grammar is specified, you can optionally specify: 'boysname','girlsname', 'surname'
|
102
|
+
|
103
|
+
|
104
|
+
Example:
|
105
|
+
|
106
|
+
```Ruby
|
107
|
+
CipherBureau::Password.memorable(:length => 12, :grammar => 'name', :name_type => 'girlsname')
|
108
|
+
=> "Hedda[)*Turi"
|
109
|
+
|
110
|
+
CipherBureau::Password.memorable(:length => 12, :grammar => 'noun', :camelize => true)
|
111
|
+
=> "Aktor2]%Hott"
|
112
|
+
```
|
113
|
+
|
114
|
+
### Measuring strength of passwords
|
115
|
+
|
116
|
+
The PasswordMeter module is a ruby implementation of the javascript algorithm found at http://www.passwordmeter.com
|
117
|
+
It will return a range from 0 to 100 depending on the complexity of the password.
|
118
|
+
|
119
|
+
Examples:
|
120
|
+
|
121
|
+
```Ruby
|
122
|
+
CipherBureau::PasswordMeter.strength('aaaaaaaa')
|
123
|
+
=> 0
|
124
|
+
CipherBureau::PasswordMeter.strength('abcdaaa1')
|
125
|
+
=> 15
|
126
|
+
CipherBureau::PasswordMeter.strength('<~%2`!-452')
|
127
|
+
=> 100
|
128
|
+
CipherBureau::PasswordMeter.strength('Aktor2]%Hott')
|
129
|
+
=> 97
|
130
|
+
CipherBureau::PasswordMeter.strength('test123')
|
131
|
+
=> 36
|
132
|
+
```
|
133
|
+
|
134
|
+
|
135
|
+
# Configuring defaults
|
136
|
+
|
137
|
+
You can configure defaults for passwrd_length and memorable passwords by placing a file in your initializers directory:
|
138
|
+
|
139
|
+
```Ruby
|
140
|
+
# config/initializers/cipher_bureau.rb
|
141
|
+
CipherBureau.configure do |config|
|
142
|
+
config.password_length = 10
|
143
|
+
config.default_memorable_options = {
|
144
|
+
country_code: 47,
|
145
|
+
camelize: true,
|
146
|
+
grammar: 'name'
|
147
|
+
}
|
148
|
+
end
|
149
|
+
```
|
150
|
+
|
151
|
+
# Loading your own dictionary
|
152
|
+
|
153
|
+
See the file db/seeds/norwegian/wordloader.rb
|
154
|
+
|
155
|
+
This file loads the Norwegian wordlist and Norwegian names into the database. It explains how to load grammars and names into the database.
|
156
|
+
It is recommended to use the same facilities as that source is using.
|
157
|
+
CipherBureau::DataLoader is loading data in chunked transactions.
|
158
|
+
|
159
|
+
The default repository for dictionaries is located on http://dictionaries.cipher-bureau.net
|
160
|
+
You can control the location of the dictionaries by setting the configuration ```language_repository```.
|
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'CipherBureau'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
Dir.glob('lib/tasks/*.rake').each { |r| import r }
|
24
|
+
|
25
|
+
|
26
|
+
Bundler::GemHelper.install_tasks
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
|
30
|
+
Rake::TestTask.new(:test) do |t|
|
31
|
+
t.libs << 'lib'
|
32
|
+
t.libs << 'test'
|
33
|
+
t.pattern = 'test/**/*_test.rb'
|
34
|
+
t.verbose = false
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
task :default => :test
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'unicode_utils'
|
3
|
+
|
4
|
+
country_code = 47
|
5
|
+
|
6
|
+
grammar_map = {
|
7
|
+
'prep' => 'preposition',
|
8
|
+
'verb' => 'verb',
|
9
|
+
'adj' => 'adjective',
|
10
|
+
'adv' => 'adverb',
|
11
|
+
'subst' => 'noun',
|
12
|
+
'interj' => 'interjection',
|
13
|
+
'det' => 'determiner',
|
14
|
+
'pron' => 'pronoun',
|
15
|
+
'verbalsubst' => 'verbalsubst',
|
16
|
+
'musikkuttr' => 'musical',
|
17
|
+
'konj' => 'conjunction',
|
18
|
+
'numeral' => 'numeral',
|
19
|
+
'sbu' => 'subjunctive',
|
20
|
+
'adjektiv' => 'adjective',
|
21
|
+
'CLB' => 'conjunction', # or correlative conjunction
|
22
|
+
'nominal' => 'determiner'
|
23
|
+
}
|
24
|
+
|
25
|
+
loader = CipherBureau::DataLoader.new(:norwegian, 1000)
|
26
|
+
|
27
|
+
puts "Loading grammar"
|
28
|
+
loader.process 'NSF-ordlisten', 'NSF-ordlisten.txt' do |str|
|
29
|
+
word, grammar = str.split(' ')
|
30
|
+
word = UnicodeUtils.downcase(word)
|
31
|
+
CipherBureau::Dictionary.create word: word.chomp, grammar: grammar_map[grammar], country_code: country_code
|
32
|
+
end
|
33
|
+
|
34
|
+
names_map = {
|
35
|
+
'surname' => 'etternavn',
|
36
|
+
'boysname' => 'guttenavn',
|
37
|
+
'girlsname' => 'jentenavn'
|
38
|
+
}
|
39
|
+
loader.chunks = 100
|
40
|
+
names_map.each do |name_type, file|
|
41
|
+
puts "Loading #{name_type}"
|
42
|
+
loader.process 'norske-navn', "#{file}.txt" do |name|
|
43
|
+
CipherBureau::Dictionary.create word: name, grammar: 'name', name_type: name_type, country_code: country_code
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
puts "Total words loaded: #{loader.words}"
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# Copyright (c) 2013 Dynamic Project Management AS
|
2
|
+
# Copyright (c) 2013 Knut I. Stenmark
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
require 'cipher_bureau/exceptions'
|
24
|
+
module CipherBureau
|
25
|
+
def self.table_name_prefix
|
26
|
+
'cipher_bureau_'
|
27
|
+
end
|
28
|
+
|
29
|
+
autoload :Statistic, 'cipher_bureau/statistic'
|
30
|
+
autoload :Dictionary, 'cipher_bureau/dictionary'
|
31
|
+
autoload :Password, 'cipher_bureau/password'
|
32
|
+
autoload :PasswordMeter, 'cipher_bureau/password_meter'
|
33
|
+
autoload :DataLoader, 'cipher_bureau/data_loader'
|
34
|
+
|
35
|
+
include ActiveSupport::Configurable
|
36
|
+
|
37
|
+
# Default password length
|
38
|
+
config_accessor :password_length
|
39
|
+
|
40
|
+
# Oprions to use for memorable passwords
|
41
|
+
#
|
42
|
+
# Valid options:
|
43
|
+
#
|
44
|
+
# :country_code - a numerical value of country_code, e.g. Norway 47
|
45
|
+
# :ascii - true of false. Use false to get words outside 7-bits range, such as nordic characters
|
46
|
+
# :grammar - legal values are: 'adjective','adverb','conjunction','determiner','interjection','name','noun',
|
47
|
+
# 'musical','numeral','preposition','pronoun','subjunctive','verb','verbalsubst',
|
48
|
+
# :name_tupe - if grammar is specified, you can optionally specify: 'boysname','girlsname', 'surname'
|
49
|
+
#
|
50
|
+
config_accessor :default_memorable_options
|
51
|
+
|
52
|
+
self.default_memorable_options ||= {}
|
53
|
+
|
54
|
+
# Sets repository location for langage files
|
55
|
+
config_accessor :language_repository
|
56
|
+
|
57
|
+
self.language_repository ||= "http://dictionaries.cipher-bureau.net"
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# Copyright (c) 2013 Dynamic Project Management AS
|
2
|
+
# Copyright (c) 2013 Knut I. Stenmark
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
require 'open-uri'
|
24
|
+
|
25
|
+
module CipherBureau
|
26
|
+
class DataLoader
|
27
|
+
attr_reader :words, :language
|
28
|
+
attr_accessor :chunks
|
29
|
+
|
30
|
+
def initialize(language, chunks = 100, words = 0, verbose = true)
|
31
|
+
@language, @chunks, @words, @verbose = language, chunks, words, verbose
|
32
|
+
end
|
33
|
+
|
34
|
+
def reader(filename)
|
35
|
+
Fiber.new do
|
36
|
+
puts "Reading file #{filename}" if @verbose
|
37
|
+
open(filename).readlines.each do |str|
|
38
|
+
Fiber.yield str
|
39
|
+
end
|
40
|
+
puts "\r#{@words}" if @verbose
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def writer(fiber, &block)
|
46
|
+
str = nil
|
47
|
+
begin
|
48
|
+
chunks.times do
|
49
|
+
ActiveRecord::Base.transaction do
|
50
|
+
break unless str = fiber.resume
|
51
|
+
yield str.chomp
|
52
|
+
@words += 1
|
53
|
+
end
|
54
|
+
return unless str
|
55
|
+
end
|
56
|
+
print "\r#{@words}" if @verbose
|
57
|
+
end while str
|
58
|
+
end
|
59
|
+
|
60
|
+
def process(*directories_and_filename, &block)
|
61
|
+
filename = ([CipherBureau.language_repository, language.to_s] + directories_and_filename).join('/')
|
62
|
+
writer(reader(filename), &block)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Copyright (c) 2013 Dynamic Project Management AS
|
2
|
+
# Copyright (c) 2013 Knut I. Stenmark
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
require 'unicode_utils'
|
24
|
+
class CipherBureau::Dictionary < ActiveRecord::Base
|
25
|
+
attr_accessible :word, :grammar, :country_code, :name_type
|
26
|
+
|
27
|
+
validates_presence_of :word, :grammar, :country_code
|
28
|
+
|
29
|
+
before_save do
|
30
|
+
self.length = word.length
|
31
|
+
self.ascii = !!(word =~ /^[a-z]+$/)
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
after_create do
|
36
|
+
CipherBureau::Statistic.register(self)
|
37
|
+
end
|
38
|
+
|
39
|
+
class << self
|
40
|
+
def random(*args)
|
41
|
+
criteria = args.extract_options!
|
42
|
+
camelize = criteria.delete(:camelize)
|
43
|
+
criteria.merge!(:length => args.first) if args.first
|
44
|
+
r = fetch_random_word(criteria)
|
45
|
+
r && (camelize ? capitalize(r.word) : r.word)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
def randomized_offset(offset)
|
50
|
+
rand(offset)
|
51
|
+
end
|
52
|
+
|
53
|
+
def fetch_random_word(criteria)
|
54
|
+
n = CipherBureau::Statistic.word_count(criteria) # get number of elements satisfying criteria
|
55
|
+
where(criteria).offset(randomized_offset(n)).limit(1).first
|
56
|
+
end
|
57
|
+
|
58
|
+
def capitalize(word)
|
59
|
+
UnicodeUtils.upcase(word[0]) + word[1..-1]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|