deluminator 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.
Files changed (2) hide show
  1. data/lib/deluminator.rb +88 -0
  2. metadata +46 -0
@@ -0,0 +1,88 @@
1
+ class Deluminator
2
+ #KEYWORDS = %w(def end collect each class module open close inject select detect reject upto downto
3
+ # this self describe context it should
4
+ # )
5
+ attr_reader :reserved
6
+
7
+ MIN_DICTIONARY_LENGTH = 4
8
+ UPVOWELS = %w(A E I O U Y)
9
+ LOWVOWELS = %w(a e i o u y)
10
+ UPPERS = ('A'..'Z').to_a - UPVOWELS
11
+ LOWERS = ('a'..'z').to_a - LOWVOWELS
12
+ VOWEL_LEN = UPVOWELS.length
13
+ NONVOWEL_LEN = UPPERS.length
14
+
15
+ def initialize(hash = {})
16
+ raise "Deluminator.new expects a hash" unless hash.is_a?(Hash)
17
+ @length_indexed_dict = hash[:length_indexed_dict] || {}
18
+ @reserved = hash[:reserved] || []
19
+ raise ":reserved value must be an array" unless @reserved.is_a?(Array)
20
+ raise ":length_indexed_dict value must be a hash" unless @length_indexed_dict.is_a?(Hash)
21
+ raise ":length_indexed_dict keys must be integers" unless @length_indexed_dict.keys.all? { |k| k.is_a?(Integer) }
22
+ end
23
+ def add_to_dictionary(text)
24
+ text.split(/\s+|[^a-zA-z]+/).each do |word|
25
+ add_one_word_to_dictionary(word)
26
+ end
27
+ end
28
+
29
+ # flattened hash of all our sub-hashes
30
+ def dictionary
31
+ hash = {}
32
+ @length_indexed_dict.each do |len, words_of_same_length|
33
+ hash.merge! words_of_same_length
34
+ end
35
+ hash
36
+ end
37
+
38
+ def deluminate(text)
39
+ result = text
40
+ # Replace the longer words first, to ensure we don't corrupt them if they contain shorter words
41
+ # (we *assume* that our random replacements don't ever match a substring of a longer replacement string -
42
+ # which is probably a good bet since the odds are close to 1 in 26**4 or 1:456976)
43
+ @length_indexed_dict.keys.sort.reverse.each do |word_len|
44
+ @length_indexed_dict[word_len].each do |word, replacement|
45
+ #regexp = Regexp.new("\\b#{word}\\b")
46
+ regexp = Regexp.new(word)
47
+ result.gsub!(regexp, replacement)
48
+ end
49
+ end
50
+ result
51
+ end
52
+
53
+ private
54
+
55
+ def add_one_word_to_dictionary(word)
56
+ return word if word.nil? || word.length < MIN_DICTIONARY_LENGTH || @reserved.include?(word)
57
+
58
+ @length_indexed_dict[word.length] ||= {}
59
+ return @length_indexed_dict[word.length][word] if @length_indexed_dict[word.length][word]
60
+
61
+ result = transmute(word)
62
+ existing = @length_indexed_dict[word.length].values
63
+ while existing.include?(result) do
64
+ result = result.next # "aaaa".next=="aaab"
65
+ end
66
+ @length_indexed_dict[word.length][word] = result
67
+ #puts @length_indexed_dict.inspect
68
+ @length_indexed_dict[word.length][word]
69
+ end
70
+
71
+ def transmute(word)
72
+ word.split('').collect do |letter|
73
+ if UPPERS.include?(letter)
74
+ if UPVOWELS.include?(letter)
75
+ UPVOWELS[rand(VOWEL_LEN)]
76
+ else
77
+ UPPERS[rand(NONVOWEL_LEN)]
78
+ end
79
+ else
80
+ if LOWVOWELS.include?(letter)
81
+ LOWVOWELS[rand(VOWEL_LEN)]
82
+ else
83
+ LOWERS[rand(NONVOWEL_LEN)]
84
+ end
85
+ end
86
+ end.join
87
+ end
88
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: deluminator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - John Baylor
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-09-20 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Consistently obfuscates any text, leaving reserved words unchanged.
15
+ email: john.baylor@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/deluminator.rb
21
+ homepage: http://rubygems.org/gems/deluminator
22
+ licenses:
23
+ - MIT
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 1.8.23
43
+ signing_key:
44
+ specification_version: 3
45
+ summary: Confuses stuff
46
+ test_files: []