flatulent 0.0.1 → 0.0.2
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/README +60 -16
- data/flatulent-0.0.2.gem +0 -0
- data/lib/flatulent/crypt/blowfish-tables.rb +190 -0
- data/lib/flatulent/crypt/blowfish.rb +109 -0
- data/lib/flatulent/crypt/cbc.rb +123 -0
- data/lib/flatulent/crypt/gost.rb +140 -0
- data/lib/flatulent/crypt/idea.rb +193 -0
- data/lib/flatulent/crypt/noise.rb +94 -0
- data/lib/flatulent/crypt/purerubystringio.rb +378 -0
- data/lib/flatulent/crypt/rijndael-tables.rb +117 -0
- data/lib/flatulent/crypt/rijndael.rb +269 -0
- data/lib/flatulent/crypt/stringxor.rb +27 -0
- data/lib/flatulent.rb +332 -121
- data/lib/flatulent.rb.bak +337 -0
- data/rails/app/controllers/flatulent_controller.rb +61 -6
- data/rails/lib/flatulent/attributes.rb +79 -0
- data/rails/lib/flatulent/crypt/blowfish-tables.rb +190 -0
- data/rails/lib/flatulent/crypt/blowfish.rb +109 -0
- data/rails/lib/flatulent/crypt/cbc.rb +123 -0
- data/rails/lib/flatulent/crypt/gost.rb +140 -0
- data/rails/lib/flatulent/crypt/idea.rb +193 -0
- data/rails/lib/flatulent/crypt/noise.rb +94 -0
- data/rails/lib/flatulent/crypt/purerubystringio.rb +378 -0
- data/rails/lib/flatulent/crypt/rijndael-tables.rb +117 -0
- data/rails/lib/flatulent/crypt/rijndael.rb +269 -0
- data/rails/lib/flatulent/fontfiles/banner.flf +2494 -0
- data/rails/lib/flatulent/fontfiles/big.flf +2204 -0
- data/rails/lib/flatulent/fontfiles/block.flf +1691 -0
- data/rails/lib/flatulent/fontfiles/bubble.flf +1630 -0
- data/rails/lib/flatulent/fontfiles/digital.flf +1286 -0
- data/rails/lib/flatulent/fontfiles/ivrit.flf +900 -0
- data/rails/lib/flatulent/fontfiles/lean.flf +1691 -0
- data/rails/lib/flatulent/fontfiles/mini.flf +899 -0
- data/rails/lib/flatulent/fontfiles/mnemonic.flf +3702 -0
- data/rails/lib/flatulent/fontfiles/script.flf +1493 -0
- data/rails/lib/flatulent/fontfiles/shadow.flf +1097 -0
- data/rails/lib/flatulent/fontfiles/slant.flf +1295 -0
- data/rails/lib/flatulent/fontfiles/small.flf +1097 -0
- data/rails/lib/flatulent/fontfiles/smscript.flf +1097 -0
- data/rails/lib/flatulent/fontfiles/smshadow.flf +899 -0
- data/rails/lib/flatulent/fontfiles/smslant.flf +1097 -0
- data/rails/lib/flatulent/fontfiles/standard.flf +2227 -0
- data/rails/lib/flatulent/fontfiles/term.flf +600 -0
- data/rails/lib/flatulent/pervasives.rb +32 -0
- data/rails/lib/flatulent/stringxor.rb +27 -0
- data/rails/lib/flatulent/text/double_metaphone.rb +356 -0
- data/rails/lib/flatulent/text/figlet/font.rb +117 -0
- data/rails/lib/flatulent/text/figlet/smusher.rb +64 -0
- data/rails/lib/flatulent/text/figlet/typesetter.rb +68 -0
- data/rails/lib/flatulent/text/figlet.rb +17 -0
- data/rails/lib/flatulent/text/levenshtein.rb +65 -0
- data/rails/lib/flatulent/text/metaphone.rb +97 -0
- data/rails/lib/flatulent/text/porter_stemming.rb +171 -0
- data/rails/lib/flatulent/text/soundex.rb +61 -0
- data/rails/lib/flatulent/text.rb +6 -0
- data/rails/lib/flatulent.rb +450 -0
- data/rails/log/development.log +14297 -0
- data/rails/log/fastcgi.crash.log +111 -0
- data/rails/log/lighttpd.access.log +3993 -0
- data/rails/log/lighttpd.error.log +111 -0
- data/rails/tmp/cache/javascripts/prototype.js-gzip-3275912-71260-1183440172 +0 -0
- data/rails/tmp/sessions/ruby_sess.32d68bc997054475 +0 -0
- data/rails/tmp/sessions/ruby_sess.4694a4b9bdf9bcf4 +0 -0
- data/rails/tmp/sessions/ruby_sess.99469fde69043a05 +0 -0
- data/rails/tmp/sessions/ruby_sess.a588c0a457345912 +0 -0
- data/rails/tmp/sessions/ruby_sess.b3344125a84a3efa +0 -0
- data/samples.rb +10 -0
- metadata +69 -3
- data/flatulent-0.0.0.gem +0 -0
data/lib/flatulent.rb
CHANGED
@@ -1,72 +1,261 @@
|
|
1
|
-
|
1
|
+
# TODO - encrypt time
|
2
|
+
# TODO - noise is image chars
|
3
|
+
# TODO - newline in value??
|
4
|
+
# TODO - vertical offset in chars
|
2
5
|
|
3
|
-
|
6
|
+
class Flatulent
|
7
|
+
Flatulent::VERSION = '0.0.2' unless defined? Flatulent::VERSION
|
8
|
+
def self.flatulent() Flatulent::VERSION end
|
9
|
+
def self.libdir() File.expand_path(__FILE__).gsub(%r/\.rb$/, '') end
|
4
10
|
|
5
|
-
|
6
|
-
require '
|
7
|
-
|
8
|
-
end
|
11
|
+
require 'cgi'
|
12
|
+
require 'base64'
|
13
|
+
require 'digest/md5'
|
9
14
|
|
10
|
-
begin
|
11
|
-
|
12
|
-
rescue LoadError
|
13
|
-
|
14
|
-
end
|
15
|
+
begin
|
16
|
+
require 'rubygems'
|
17
|
+
rescue LoadError
|
18
|
+
end
|
15
19
|
|
16
|
-
begin
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
20
|
+
begin
|
21
|
+
$:.unshift libdir
|
22
|
+
require 'text/figlet'
|
23
|
+
require 'crypt/blowfish'
|
24
|
+
require 'pervasives'
|
25
|
+
require 'attributes'
|
26
|
+
ensure
|
27
|
+
$:.shift
|
28
|
+
end
|
29
|
+
|
30
|
+
class Error < ::StandardError; end
|
31
|
+
class EncryptionError < Error; end
|
32
|
+
class TimeBombError < Error; end
|
21
33
|
|
22
|
-
begin
|
23
|
-
require 'attributes'
|
24
|
-
rescue LoadError
|
25
|
-
require libdir + 'attributes'
|
26
|
-
end
|
27
34
|
|
28
|
-
class Flatulent
|
29
35
|
singleton_class =
|
30
36
|
class << self
|
31
37
|
self
|
32
38
|
end
|
33
39
|
|
34
40
|
singleton_class.module_eval do
|
35
|
-
attribute('libdir'){ File.expand_path(__FILE__).gsub(%r/\.rb$/, '') }
|
36
41
|
|
37
42
|
attribute('fontdir'){ File.join libdir, 'fontfiles' }
|
38
43
|
|
39
44
|
attribute('style'){ Hash[
|
40
|
-
'white-space' => 'pre
|
45
|
+
'white-space' => 'pre',
|
41
46
|
'font-family' => 'monospace',
|
42
47
|
'font-weight' => 'bold',
|
43
|
-
'
|
44
|
-
'padding' => '11px',
|
48
|
+
'font-size' => 'medium',
|
45
49
|
'background' => '#ffc',
|
46
|
-
'color' => '
|
50
|
+
'color' => '#00f',
|
51
|
+
'margin' => '2px',
|
52
|
+
'padding' => '2px',
|
53
|
+
'display' => 'table',
|
47
54
|
] }
|
48
55
|
|
49
56
|
attribute('noise_style'){ Hash[
|
50
57
|
'color' => '#ccc',
|
51
|
-
'font-style' => 'oblique',
|
52
58
|
] }
|
59
|
+
|
60
|
+
attribute('key'){ default_key }
|
61
|
+
|
62
|
+
def valid? keywords = {}
|
63
|
+
begin
|
64
|
+
validate! keywords
|
65
|
+
true
|
66
|
+
rescue EncryptionError, TimeBombError
|
67
|
+
false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def validate! keywords = {}
|
72
|
+
keywords = keywords['flatulent'] if keywords.has_key?('flatulent')
|
73
|
+
keywords = keywords[:flatulent] if keywords.has_key?(:flatulent)
|
74
|
+
|
75
|
+
opts = getopts keywords
|
76
|
+
|
77
|
+
captcha = opts['c'] or raise 'no captcha'
|
78
|
+
string = opts['s'] or raise 'no string'
|
79
|
+
time = opts['t'] or raise 'no time'
|
80
|
+
|
81
|
+
expected = zeroh(decrypt(string))
|
82
|
+
actual = zeroh(captcha)
|
83
|
+
raise EncryptionError, "expected #{ expected } got #{ actual }" unless
|
84
|
+
expected == actual
|
85
|
+
|
86
|
+
timebomb = Time.at(Integer(decrypt(time))).utc rescue(raise("bad time #{ time }"))
|
87
|
+
raise TimeBombError unless Time.now.utc <= timebomb
|
88
|
+
|
89
|
+
return actual
|
90
|
+
end
|
91
|
+
|
92
|
+
def zeroh string
|
93
|
+
string.gsub(%r/[0Oo]/, '0') # ignore diffs between 0/o/O
|
94
|
+
end
|
95
|
+
|
96
|
+
def blowfish
|
97
|
+
@blowfish ||= Hash.new{|h,k| h[k] = Crypt::Blowfish.new(key)}
|
98
|
+
end
|
99
|
+
|
100
|
+
def munge string
|
101
|
+
string.strip.downcase
|
102
|
+
end
|
103
|
+
|
104
|
+
def encrypt string
|
105
|
+
Base64.encode64(blowfish[key].encrypt_string(string.to_s)).chop # kill "\n"
|
106
|
+
end
|
107
|
+
|
108
|
+
def decrypt string
|
109
|
+
munge(blowfish[key].decrypt_string(Base64.decode64("#{ string }\n")))
|
110
|
+
end
|
111
|
+
|
112
|
+
def getopts options
|
113
|
+
lambda do |key, *default|
|
114
|
+
default = default.first
|
115
|
+
break options[key] if options.has_key?(key)
|
116
|
+
key = key.to_s
|
117
|
+
break options[key] if options.has_key?(key)
|
118
|
+
key = key.to_sym
|
119
|
+
break options[key] if options.has_key?(key)
|
120
|
+
break default
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def default_key
|
125
|
+
#attribute('default_key') do
|
126
|
+
return @default_key if defined? @default_key
|
127
|
+
require 'socket'
|
128
|
+
hostname = Socket.gethostname
|
129
|
+
maddr = mac_address rescue nil
|
130
|
+
warn "could not determine mac addresss!" unless maddr
|
131
|
+
#puts(( Digest::MD5.hexdigest "--#{ hostname }--#{ maddr }--" ))
|
132
|
+
#Digest::MD5.hexdigest "--#{ hostname }--#{ maddr }--"
|
133
|
+
#@default_key = "--#{ hostname }--#{ maddr }--"
|
134
|
+
@default_key = "--#{ hostname }--#{ maddr }--"
|
135
|
+
end
|
136
|
+
|
137
|
+
def mac_address
|
138
|
+
return @mac_address if defined? @mac_address
|
139
|
+
re = %r/[^:\-](?:[0-9A-F][0-9A-F][:\-]){5}[0-9A-F][0-9A-F][^:\-]/io
|
140
|
+
cmds = '/sbin/ifconfig', '/bin/ifconfig', 'ifconfig', 'ipconfig /all'
|
141
|
+
|
142
|
+
null = test(?e, '/dev/null') ? '/dev/null' : 'NUL'
|
143
|
+
|
144
|
+
lines = nil
|
145
|
+
cmds.each do |cmd|
|
146
|
+
stdout = IO.popen("#{ cmd } 2> #{ null }"){|fd| fd.readlines} rescue next
|
147
|
+
next unless stdout and stdout.size > 0
|
148
|
+
lines = stdout and break
|
149
|
+
end
|
150
|
+
raise "all of #{ cmds.join ' ' } failed" unless lines
|
151
|
+
|
152
|
+
candidates = lines.select{|line| line =~ re}
|
153
|
+
raise 'no mac address candidates' unless candidates.first
|
154
|
+
candidates.map!{|c| c[re]}
|
155
|
+
|
156
|
+
maddr = candidates.first
|
157
|
+
raise 'no mac address found' unless maddr
|
158
|
+
|
159
|
+
maddr.strip!
|
160
|
+
maddr.instance_eval{ @list = candidates; def list() @list end }
|
161
|
+
|
162
|
+
@mac_address = maddr
|
163
|
+
end
|
164
|
+
|
165
|
+
def figlet options = {}
|
166
|
+
new(options).figlet
|
167
|
+
end
|
168
|
+
def figlets options = {}
|
169
|
+
new(options).figlets
|
170
|
+
end
|
171
|
+
def element options = {}
|
172
|
+
new(options).element
|
173
|
+
end
|
174
|
+
def form_tags options = {}
|
175
|
+
new(options).form_tags
|
176
|
+
end
|
177
|
+
def form options = {}
|
178
|
+
new(options).form
|
179
|
+
end
|
180
|
+
|
181
|
+
def latest_prototype_lib
|
182
|
+
'http://www.prototypejs.org/assets/2007/6/20/prototype.js'
|
183
|
+
end
|
184
|
+
def require_prototype
|
185
|
+
%Q`
|
186
|
+
<script type="text/javascript">
|
187
|
+
var prototype = true;
|
188
|
+
try{ Prototype; } catch(e) { prototype = false };
|
189
|
+
if(!prototype){
|
190
|
+
var js = document.createElement('script');
|
191
|
+
js.type='text/javascript';
|
192
|
+
js.src='/javascripts/prototype.js';
|
193
|
+
document.getElementsByTagName('head')[0].appendChild(js);
|
194
|
+
}
|
195
|
+
</script>
|
196
|
+
<script type="text/javascript">
|
197
|
+
var prototype = true;
|
198
|
+
try{ Prototype; } catch(e) { prototype = false };
|
199
|
+
if(!prototype){
|
200
|
+
var js = document.createElement('script');
|
201
|
+
js.type='text/javascript';
|
202
|
+
js.src='#{ latest_prototype_lib }';
|
203
|
+
document.getElementsByTagName('head')[0].appendChild(js);
|
204
|
+
}
|
205
|
+
</script>
|
206
|
+
`
|
207
|
+
end
|
208
|
+
def javascript options = {}
|
209
|
+
id = options[:id] || options['id'] || 'flatulent'
|
210
|
+
url = options[:url] || options['url'] || '/flatulent/captcha'
|
211
|
+
%Q`
|
212
|
+
#{ require_prototype }
|
213
|
+
<script type="text/javascript">
|
214
|
+
new Ajax.Updater('#{ id }', '#{ url }', { method: 'get' });
|
215
|
+
</script>
|
216
|
+
`
|
217
|
+
end
|
218
|
+
def ajax options = {}
|
219
|
+
id = options[:id] || options['id'] || 'flatulent'
|
220
|
+
%Q`
|
221
|
+
<div id="#{ id }"></div>
|
222
|
+
#{ Flatulent.javascript }
|
223
|
+
`
|
224
|
+
end
|
53
225
|
end
|
54
226
|
|
55
227
|
singleton_class.attributes.each{|a| attribute(a){ self.class.send a}}
|
56
228
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
229
|
+
attribute 'string'
|
230
|
+
attribute 'size'
|
231
|
+
attribute 'font'
|
232
|
+
attribute 'noise'
|
233
|
+
attribute 'id'
|
234
|
+
attribute 'action'
|
235
|
+
attribute 'ttl'
|
236
|
+
|
237
|
+
attribute 'figlet'
|
238
|
+
attribute 'figlets'
|
239
|
+
attribute 'element'
|
240
|
+
attribute 'form_tags'
|
241
|
+
attribute 'form'
|
242
|
+
|
243
|
+
def initialize arg = {}
|
244
|
+
if Hash === arg
|
245
|
+
opt = getopts arg
|
246
|
+
@size = Integer opt[ 'size', 4 ]
|
247
|
+
@string = String opt[ 'string', generate_random_string ]
|
248
|
+
else
|
249
|
+
opt = getopts Hash.new
|
250
|
+
@string = String arg
|
251
|
+
@size = @string.size
|
252
|
+
end
|
61
253
|
|
62
|
-
@
|
63
|
-
@
|
64
|
-
@
|
65
|
-
@
|
66
|
-
@
|
67
|
-
@id = opt[ 'id', 'flatulent' ]
|
68
|
-
@action = opt[ 'action' ]
|
69
|
-
@ttl = Integer opt[ 'ttl', 5 * 60 ] # seconds!
|
254
|
+
@font = String opt[ 'font', 'big' ]
|
255
|
+
@noise = Float opt[ 'noise', 0.04 ]
|
256
|
+
@id = String opt[ 'id', 'flatulent' ]
|
257
|
+
@action = String opt[ 'action' ]
|
258
|
+
@ttl = Integer opt[ 'ttl', 256 ]
|
70
259
|
|
71
260
|
figlet!
|
72
261
|
element!
|
@@ -76,21 +265,19 @@ class Flatulent
|
|
76
265
|
|
77
266
|
def generate_random_string
|
78
267
|
chars = ('A' .. 'Z').to_a + ('1' .. '9').to_a ### zero is too much like o/O
|
79
|
-
Array.new(@size).map{ chars[rand(chars.size - 1)]}.join
|
80
|
-
end
|
81
|
-
|
82
|
-
def getopts options
|
83
|
-
self.class.getopts options
|
268
|
+
Array.new(@size).map{ chars[rand(chars.size - 1)]}.join
|
84
269
|
end
|
85
270
|
|
86
271
|
def figlet!
|
87
|
-
spaced = @string.split(%r//).join(' ')
|
272
|
+
spaced = @string.split(%r//).join #.join(' ')
|
88
273
|
fontfile = File.join fontdir, "#{ @font }.flf"
|
89
274
|
font = Text::Figlet::Font.new fontfile
|
90
275
|
typesetter = Text::Figlet::Typesetter.new font
|
276
|
+
@figlets = []
|
277
|
+
chars = spaced.split %r//
|
278
|
+
chars.each{|char| @figlets << typesetter[char]}
|
91
279
|
@figlet = typesetter[spaced]
|
92
280
|
end
|
93
|
-
attr 'figlet'
|
94
281
|
|
95
282
|
def element!
|
96
283
|
rows = []
|
@@ -105,61 +292,125 @@ class Flatulent
|
|
105
292
|
when %r/\n/o
|
106
293
|
"<br>"
|
107
294
|
when %r/\s/o
|
295
|
+
#rand > 0.42 ? " " : " "
|
108
296
|
" "
|
109
297
|
when %r/([^\s])/o
|
110
|
-
$1
|
298
|
+
CGI.escapeHTML $1
|
111
299
|
end
|
300
|
+
Array.new(rand(42)){ content = "<span>#{ content }</span>"}
|
112
301
|
row << content
|
113
302
|
rows << (row = []) unless idx == last
|
114
303
|
end
|
115
304
|
|
305
|
+
noisy = %W` | / - _ ( ) \ `
|
116
306
|
(@noise * chars.size).ceil.times do
|
117
307
|
y = rand(rows.size - 1)
|
118
308
|
x = rand(rows.first.size - 1)
|
119
|
-
next if rows[y][x]
|
120
|
-
|
121
|
-
rows[y][x] =
|
309
|
+
next if rows[y][x] =~ %r"br"
|
310
|
+
char = noisy[ rand(noisy.size) ]
|
311
|
+
rows[y][x] = char
|
122
312
|
end
|
123
313
|
|
124
314
|
content = rows.join
|
125
315
|
@element = "<pre id='#{ @id }_element' style='#{ css }'>#{ content }</pre>"
|
126
316
|
end
|
127
|
-
|
317
|
+
|
318
|
+
=begin
|
319
|
+
|
320
|
+
def element!
|
321
|
+
cells = []
|
322
|
+
|
323
|
+
@figlets.each do |figlet|
|
324
|
+
rows = []
|
325
|
+
rows << (row = [])
|
326
|
+
|
327
|
+
offset_t = Array.new(rand(4)).map{ "\n"}
|
328
|
+
offset_b = Array.new(rand(4)).map{ "\n"}
|
329
|
+
|
330
|
+
offset_l = Array.new(rand(4)).map{ " "}
|
331
|
+
offset_r = Array.new(rand(4)).map{ " "}
|
332
|
+
|
333
|
+
chars = offset_t + figlet.split(%r//) + offset_b
|
334
|
+
size = chars.size
|
335
|
+
last = size - 1
|
336
|
+
#drawn = chars.select{|char| char !~ %r/\s/}
|
337
|
+
drawn = %w` | / \ < > v ^ - _ ( ) `
|
338
|
+
|
339
|
+
chars.each_with_index do |char, idx|
|
340
|
+
content =
|
341
|
+
case char
|
342
|
+
when %r/\n/o
|
343
|
+
"<br>"
|
344
|
+
when %r/\s/o
|
345
|
+
#rand > 0.42 ? " " : " "
|
346
|
+
" "
|
347
|
+
when %r/([^\s])/o
|
348
|
+
CGI.escapeHTML $1
|
349
|
+
end
|
350
|
+
#rand(10).times{ content = "<span>#{ content }</span>" }
|
351
|
+
row << content
|
352
|
+
rows << (row = []) unless idx == last
|
353
|
+
end
|
354
|
+
|
355
|
+
noisy = %w` | / \ - _ ( ) `
|
356
|
+
(@noise * chars.size).ceil.times do
|
357
|
+
y = rand(rows.size - 1)
|
358
|
+
x = rand(rows.first.size - 1)
|
359
|
+
next if rows[y][x] == "<br>"
|
360
|
+
char = noisy[ rand(noisy.size) ]
|
361
|
+
rows[y][x] = char
|
362
|
+
end
|
363
|
+
|
364
|
+
content = rows.join
|
365
|
+
cells << content
|
366
|
+
end
|
367
|
+
|
368
|
+
formatted = lambda{|x| "<pre class='#{ @id }_figlet' style='#{ css }'>#{ x }</pre>"}
|
369
|
+
|
370
|
+
@element =
|
371
|
+
"<table id='#{ @id }_element' border='0' cellpadding='0' cellspacing='0' bgcolor='#{ style["background"] }'><tr>" <<
|
372
|
+
cells.map{|cell| "<td>#{ formatted[cell] }</td>"}.join <<
|
373
|
+
"</tr></table>"
|
374
|
+
end
|
375
|
+
=end
|
128
376
|
|
129
377
|
def css
|
130
|
-
style
|
378
|
+
css_for style
|
131
379
|
end
|
132
380
|
def noise_css
|
133
|
-
noise_style
|
381
|
+
css_for noise_style
|
382
|
+
end
|
383
|
+
|
384
|
+
def css_for hash
|
385
|
+
hash.map{|kv| kv.join ':' }.join ';'
|
134
386
|
end
|
135
387
|
|
136
388
|
def form_tags!
|
137
389
|
n = @string.scan(%r/\w/).size
|
390
|
+
string = @string
|
391
|
+
timebomb = Time.now.utc.to_i + @ttl
|
138
392
|
@form_tags = <<-html
|
139
393
|
#{ element }
|
140
394
|
<p id='#{ @id }_instructions'>
|
141
|
-
Please enter the #{ n } large characters shown.
|
395
|
+
Please enter the #{ n } large characters (A-Z, 1-9) shown.
|
142
396
|
</p>
|
143
|
-
<input type='textarea' name='#{ @id }[
|
144
|
-
<input type='hidden' name='#{ @id }[
|
145
|
-
<input type='hidden' name='#{ @id }[
|
397
|
+
<input type='textarea' name='#{ @id }[c]' id='#{ @id }_textarea' />
|
398
|
+
<input type='hidden' name='#{ @id }[s]' id='#{ @id }_e' value='#{ encrypt string }' />
|
399
|
+
<input type='hidden' name='#{ @id }[t]' id='#{ @id }_v' value='#{ encrypt timebomb }' />
|
146
400
|
html
|
147
401
|
end
|
148
|
-
|
402
|
+
alias_method 'to_html', 'form_tags'
|
149
403
|
|
150
|
-
def
|
151
|
-
|
404
|
+
def encrypt string
|
405
|
+
self.class.encrypt string.to_s
|
152
406
|
end
|
153
407
|
|
154
|
-
def
|
155
|
-
self.class.
|
156
|
-
end
|
157
|
-
def self.munge string
|
158
|
-
string.downcase.strip.gsub(%r/[0Oo]/, '0') ### note that 0 (zero) looks like O and o
|
408
|
+
def encrypted
|
409
|
+
self.class.encrypt @string
|
159
410
|
end
|
160
411
|
|
161
|
-
def
|
162
|
-
|
412
|
+
def munge string
|
413
|
+
self.class.munge string
|
163
414
|
end
|
164
415
|
|
165
416
|
def form!
|
@@ -171,69 +422,29 @@ class Flatulent
|
|
171
422
|
</form>
|
172
423
|
html
|
173
424
|
end
|
174
|
-
attr 'form'
|
175
|
-
alias_method 'to_html', 'form'
|
176
425
|
|
177
426
|
def to_html
|
178
|
-
|
427
|
+
element
|
179
428
|
end
|
180
429
|
|
181
430
|
def to_s
|
182
431
|
form
|
183
432
|
end
|
184
433
|
|
185
|
-
|
186
|
-
|
187
|
-
TTLError = TimeToLiveError
|
188
|
-
|
189
|
-
def self.valid? keywords = {}
|
190
|
-
begin
|
191
|
-
validate! keywords
|
192
|
-
true
|
193
|
-
rescue MD5Error, TTLError
|
194
|
-
false
|
195
|
-
end
|
434
|
+
def getopts options
|
435
|
+
self.class.getopts options
|
196
436
|
end
|
437
|
+
end
|
197
438
|
|
198
|
-
|
199
|
-
keywords = keywords['flatulent'] if keywords.has_key?('flatulent')
|
200
|
-
keywords = keywords[:flatulent] if keywords.has_key?(:flatulent)
|
201
|
-
|
202
|
-
opts = getopts keywords
|
203
|
-
|
204
|
-
textarea = opts['t']
|
205
|
-
md5 = opts['m']
|
206
|
-
timestamp = Integer opts['v']
|
207
|
-
|
208
|
-
raise MD5Error unless Digest::MD5.hexdigest(munge(textarea)) == md5
|
209
|
-
raise TimeToLiveError unless Time.now.utc <= Time.at(timestamp).utc
|
210
|
-
true
|
211
|
-
end
|
439
|
+
def Flatulent(*a, &b) Flatulent.new(*a, &b) end
|
212
440
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
break options[key] if options.has_key?(key)
|
221
|
-
break default
|
222
|
-
end
|
223
|
-
end
|
441
|
+
if $0 == __FILE__
|
442
|
+
#string = rand.to_s
|
443
|
+
#puts Flatulent(string)
|
444
|
+
#Flatulent.validate! :t => string, :e => Flatulent.encrypt(string), :v => (Time.now.utc.to_i + 60)
|
445
|
+
#e = Flatulent.encrypt('foobar')
|
446
|
+
#p e
|
447
|
+
#p Flatulent.decrypt(e)
|
224
448
|
|
225
|
-
|
226
|
-
new(options).form
|
227
|
-
end
|
228
|
-
def self.element options = {}
|
229
|
-
new(options).element
|
230
|
-
end
|
231
|
-
def self.form_tags options = {}
|
232
|
-
new(options).form_tags
|
233
|
-
end
|
234
|
-
def self.figlet options = {}
|
235
|
-
new(options).figlet
|
236
|
-
end
|
449
|
+
puts Flatulent.figlet('foobar')
|
237
450
|
end
|
238
|
-
|
239
|
-
def Flatulent(*a, &b) Flatulent.new(*a, &b) end
|