sixword 0.3.1 → 0.3.2

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
  SHA1:
3
- metadata.gz: fc9f0517fd216584e553dc2e71e960bdd0b25848
4
- data.tar.gz: 31a69ccaf02db205bf290d384fe705491ac6be11
3
+ metadata.gz: 412a951ad1786d3f978ebc77305e6b7094004b36
4
+ data.tar.gz: 1a70321549259a131a8a10a536117d29a529110a
5
5
  SHA512:
6
- metadata.gz: 6d6cfc2a72925aaa382748c85d7e803668f5df4b9a41a6a1421ea3a26ffa738650f04013bb33ee6a6f9f5957cb09d1bf2c87610825249291d158d7d1846374c9
7
- data.tar.gz: 952b8f2e92c338863d39e39e59a83c41aae3e5c24e592ea770426d7353561624474be41a96869fd67c833b5f4963cda738d79e58cc89d9731c3b5700322c7c10
6
+ metadata.gz: 9a2ca1765246ff2b0df8e4ae6b6f8554abec1fbbf7c07478b5e9b36ea38e7b34cb22e352b8c49c4786e9ebaf85927a3d270c48f005fa7e8fba4a00ab24ea09b0
7
+ data.tar.gz: 0b44ad6d9bd5c7d2b7d0c5ddf9272357be00bf4e1917a46321c595afd72d754a33eae2eda1af3c503539f388427345b59d8ffc81e0505e544b139e910845d760
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --color
2
+ --require spec_helper
2
3
  --format progress
@@ -0,0 +1,174 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2015-11-21 23:48:38 -0800 using RuboCop version 0.35.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
10
+ Style/StringLiterals:
11
+ Enabled: false
12
+
13
+ # Offense count: 3
14
+ Lint/LiteralInCondition:
15
+ Enabled: false
16
+
17
+ # Offense count: 6
18
+ Metrics/AbcSize:
19
+ Max: 50
20
+
21
+ # Offense count: 1
22
+ Metrics/BlockNesting:
23
+ Max: 4
24
+
25
+ # Offense count: 1
26
+ # Configuration parameters: CountComments.
27
+ Metrics/ClassLength:
28
+ Enabled: false
29
+
30
+ # Offense count: 4
31
+ Metrics/CyclomaticComplexity:
32
+ Max: 15
33
+
34
+ # Offense count: 12
35
+ # Configuration parameters: CountComments.
36
+ Metrics/MethodLength:
37
+ Max: 45
38
+ Exclude:
39
+ - bin/sixword
40
+
41
+ # Offense count: 2
42
+ # Configuration parameters: CountComments.
43
+ Metrics/ModuleLength:
44
+ Enabled: false
45
+
46
+ # Offense count: 3
47
+ Metrics/PerceivedComplexity:
48
+ Max: 15
49
+
50
+ # Offense count: 256
51
+ # Cop supports --auto-correct.
52
+ Style/AlignArray:
53
+ Exclude:
54
+ - 'lib/sixword/words.rb'
55
+
56
+ # Offense count: 5
57
+ Style/ConstantName:
58
+ Enabled: false
59
+
60
+ # Configuration parameters: Exclude.
61
+ #
62
+ # We could re-enable this if it understood that the top level module should
63
+ # *not* be documented in files that are not the first to define it.
64
+ #
65
+ Style/Documentation:
66
+ Enabled: false
67
+ Exclude:
68
+ - 'spec/**/*'
69
+ - 'test/**/*'
70
+
71
+ # ********************************
72
+ # Disagree with these style points
73
+ # ********************************
74
+
75
+ Style/DotPosition:
76
+ Enabled: false
77
+ Style/DoubleNegation:
78
+ Enabled: false
79
+ Style/EmptyLines:
80
+ Enabled: false
81
+ Style/EmptyLinesAroundClassBody:
82
+ Enabled: false
83
+ Style/EmptyLinesAroundMethodBody:
84
+ Enabled: false
85
+ Style/EmptyLinesAroundModuleBody:
86
+ Enabled: false
87
+ Style/GuardClause:
88
+ Enabled: false
89
+
90
+ # Don't favor modifier style ever.
91
+ Style/IfUnlessModifier:
92
+ Enabled: false
93
+ Style/WhileUntilModifier:
94
+ Enabled: false
95
+
96
+ Style/InfiniteLoop:
97
+ Enabled: false
98
+ Style/PercentLiteralDelimiters:
99
+ PreferredDelimiters:
100
+ '%w': '{}'
101
+ '%W': '{}'
102
+ Style/RaiseArgs:
103
+ EnforcedStyle: compact
104
+ Style/RedundantReturn:
105
+ Enabled: false
106
+ Style/Alias:
107
+ Enabled: false
108
+ Style/SignalException:
109
+ EnforcedStyle: only_raise
110
+ Style/SpaceAroundEqualsInParameterDefault:
111
+ EnforcedStyle: no_space
112
+
113
+ # Arguable
114
+ # Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
115
+ Style/SpaceInsideBlockBraces:
116
+ Enabled: false
117
+
118
+ # Arguable
119
+ # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SupportedStyles.
120
+ Style/SpaceInsideHashLiteralBraces:
121
+ Enabled: false
122
+
123
+ # TODO this is affected by rubocop bug
124
+ # https://github.com/bbatsov/rubocop/issues/2448
125
+ #
126
+ # Offense count: 27
127
+ # Cop supports --auto-correct.
128
+ # Configuration parameters: EnforcedStyleForMultiline, SupportedStyles.
129
+ Style/TrailingComma:
130
+ # SupportedStyles:
131
+ # - comma
132
+ # - no_comma
133
+ EnforcedStyleForMultiline: comma
134
+
135
+ # Don't favor %w for arrays of words.
136
+ Style/WordArray:
137
+ Enabled: false
138
+
139
+ # ********************************
140
+
141
+ # Configuration parameters: AllowedVariables.
142
+ Style/GlobalVars:
143
+ Exclude:
144
+ - 'spec/spec_helper.rb'
145
+
146
+ # I disagree with this cop for the specific case of
147
+ # if !foo.empty?
148
+ # because I think it's a shame that ruby has no nonempty? predicate, and it's
149
+ # clearer if the double negative is all on the RHS.
150
+ #
151
+ Style/NegatedIf:
152
+ Exclude:
153
+ - 'lib/sixword/cli.rb'
154
+
155
+ # Torn on this one, not really sure what improves clarity.
156
+ # TODO
157
+ # Offense count: 7
158
+ # Cop supports --auto-correct.
159
+ Style/SpaceAfterColon:
160
+ Exclude:
161
+ - 'lib/sixword.rb'
162
+ - 'lib/sixword/cli.rb'
163
+
164
+ # Offense count: 2
165
+ Style/SpaceInsideBrackets:
166
+ Exclude:
167
+ - 'lib/sixword/words.rb'
168
+
169
+ # Offense count: 2
170
+ # Cop supports --auto-correct.
171
+ Style/SpecialGlobalVars:
172
+ Exclude:
173
+ - 'bin/sixword'
174
+ - 'sixword.gemspec'
@@ -0,0 +1,3 @@
1
+ ---
2
+ inherit_from:
3
+ - .rubocop-disables.yml
@@ -0,0 +1,40 @@
1
+ # Change Log
2
+ All notable changes to Sixword should be documented in this file.
3
+ This project adheres to [Semantic Versioning](http://semver.org).
4
+
5
+ ## [Unreleased]
6
+
7
+ ## [0.3.2] -- 2015-11-25
8
+
9
+ - Add lots of documentation and a change log!
10
+ - Upgrade tests to rspec 3.
11
+ - Introduce rubocop style config and fix lots of warnings.
12
+ - Make `sixword --version` actually work.
13
+
14
+ ## [0.3.1] -- 2015-03-21
15
+
16
+ - Run tests on travis on various ruby versions.
17
+ - Fix tests on ruby 2.0+
18
+ - Add `-e` option flag to the CLI.
19
+
20
+ ## [0.3.0] -- 2014-07-10
21
+
22
+ - Fix handling of leading null bytes.
23
+
24
+ ## [0.2.0] -- 2013-09-27
25
+
26
+ - Add a command line interface, `sixword`.
27
+ - Handle various forms of hexadecimal notations, including colon or whitespace
28
+ delimited fingerprints.
29
+
30
+ ## [0.1.0] -- 2013-09-26
31
+
32
+ - Add and implement custom padding scheme for strings that are not a multiple
33
+ of 8 bytes.
34
+ - Add lots of tests and refactor the code.
35
+
36
+ ## [0.0.1] -- 2013-09-25
37
+
38
+ - Initial public release
39
+
40
+ <!-- vim: set tw=79 : -->
data/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # Sixword
2
2
 
3
- ![Build status](https://travis-ci.org/ab/sixword.svg)
3
+ [![Gem Version](https://badge.fury.io/rb/sixword.svg)](https://rubygems.org/gems/sixword)
4
+ [![Build status](https://travis-ci.org/ab/sixword.svg)](https://travis-ci.org/ab/sixword)
5
+ [![Code Climate](https://codeclimate.com/github/ab/sixword.svg)](https://codeclimate.com/github/ab/sixword)
6
+ [![Inline Docs](http://inch-ci.org/github/ab/sixword.svg?branch=master)](http://www.rubydoc.info/github/ab/sixword/master)
4
7
 
5
8
  Sixword implements the 6-word binary encoding created for S/Key (tm) and
6
9
  standardized by RFC 2289, RFC 1760, and RFC 1751. Binary data may be
@@ -46,9 +49,69 @@ Or install it yourself as:
46
49
 
47
50
  $ gem install sixword
48
51
 
49
- ## Usage
52
+ ## Usage: Command Line
50
53
 
51
- TODO: Write usage instructions here
54
+ Sixword operates similarly to `base64(1)`, it operates on a file or on STDIN in two modes:
55
+
56
+ - encode: accept binary data (or hexadecimal in hex modes) and print six-word
57
+ encoded data on stdout.
58
+ - decode: accept six-word encoded data and print binary data (or hex) on
59
+ stdout.
60
+
61
+ ### Examples
62
+
63
+ Normal encoding and decoding
64
+
65
+ $ sixword <<< 'Testing'
66
+ BEAK NET SITE ROTH SWIM FORM
67
+
68
+ $ sixword -d <<< 'BEAK NET SITE ROTH SWIM FORM'
69
+ Testing
70
+
71
+ $ sixword -d <<< 'beak net site roth swim form'
72
+ Testing
73
+
74
+ The same data, but hex encoded
75
+
76
+ $ sixword -H <<< '54:65:73:74:69:6e:67:0a'
77
+ BEAK NET SITE ROTH SWIM FORM
78
+
79
+ $ sixword -dH <<< 'BEAK NET SITE ROTH SWIM FORM'
80
+ 54657374696e670a
81
+
82
+ $ sixword -dF <<< 'BEAK NET SITE ROTH SWIM FORM'
83
+ 5465 7374 696E 670A
84
+
85
+ $ sixword -d -S colons <<< 'BEAK NET SITE ROTH SWIM FORM'
86
+ 54:65:73:74:69:6e:67:0a
87
+
88
+ Error handling
89
+
90
+ $ sixword -d <<< 'BEAK NET SITE ROTH SWIM FOR'
91
+ sixword: Parity bits do not match
92
+ [exit status 3]
93
+
94
+ $ sixword -p <<< '.'
95
+ sixword: Must pad bytes to multiple of 8 or use pad_encode
96
+
97
+ ## Usage: Library
98
+
99
+ See the [YARD documentation](http://www.rubydoc.info/github/ab/sixword/master).
100
+ The top-level `Sixword` module contains the main API (`Sixword.encode` and
101
+ `Sixword.decode`), while various utilities can be found in `Sixword::Hex` and
102
+ `Sixword::Lib`. Most of the code powering the command line interface is in
103
+ `Sixword::CLI`.
104
+
105
+ >> require 'sixword'
106
+
107
+ >> Sixword.encode('Hi world')
108
+ => ["ACRE", "ADEN", "INN", "SLID", "MAD", "PAP"]
109
+
110
+ >> Sixword.decode(["ACRE", "ADEN", "INN", "SLID", "MAD", "PAP"])
111
+ => 'Hi world'
112
+
113
+ >> Sixword.decode("acre aden inn slid mad pap")
114
+ => 'Hi world'
52
115
 
53
116
  ## Contributing
54
117
 
data/Rakefile CHANGED
@@ -13,4 +13,3 @@ def alias_task(alias_task, original)
13
13
  task alias_task, Rake.application[original].arg_names => original
14
14
  end
15
15
  alias_task(:test, :spec)
16
-
@@ -55,6 +55,10 @@ Options:
55
55
  $stderr.puts opts, ''
56
56
  exit 0
57
57
  end
58
+ opts.on('-v', '--version', 'Print version number', ' ') do
59
+ puts 'sixword ' + Sixword::VERSION
60
+ exit 0
61
+ end
58
62
 
59
63
  #
60
64
 
@@ -87,7 +91,12 @@ Options:
87
91
  end
88
92
  end
89
93
 
90
- optparse.parse!
94
+ begin
95
+ optparse.parse!
96
+ rescue OptionParser::InvalidOption => err
97
+ puts_err(err.message)
98
+ exit 1
99
+ end
91
100
 
92
101
  case ARGV.length
93
102
  when 0
@@ -4,43 +4,158 @@ require_relative 'sixword/lib'
4
4
  require_relative 'sixword/version'
5
5
  require_relative 'sixword/words'
6
6
 
7
+ # Sixword, a binary encoder using the 6-word scheme from S/key standardized by
8
+ # RFC 2289, RFC 1760, and RFC 1751.
9
+ #
10
+ # All of the public methods are static methods on the Sixword module, for
11
+ # example {Sixword.encode} and {Sixword.decode}.
12
+ #
13
+ # The <tt>sixword</tt> command line interface and corresponding {Sixword::CLI}
14
+ # class is also very convenient for more complex use. It supports a variety of
15
+ # different styles for translating binary data and hexadecimal fingerprints.
16
+ #
17
+ # These hexadecimal methods are implemented in the {Sixword::Hex} module.
18
+ #
7
19
  module Sixword
8
20
 
9
21
  # Parent class for inputs that could plausibly occur at runtime.
10
22
  class InputError < ArgumentError; end
11
23
 
24
+ # Raised when the parity check fails
12
25
  class InvalidParity < InputError; end
26
+
27
+ # Raised in decoding when an unrecognized word is encountered
13
28
  class UnknownWord < InputError; end
29
+
30
+ # Raised in decoding when a word of invalid format is encountered
14
31
  class InvalidWord < InputError; end
15
32
 
33
+ # Encode a string of bytes in six-word encoding. If you want to use the
34
+ # custom padding scheme for inputs that are not a multiple of 8 in length,
35
+ # use Sixword.pad_encode instead.
36
+ #
37
+ # @param byte_string [String] Length must be a multiple of 8
38
+ # @return [Array<String>] an array of string words
39
+ #
40
+ # @raise Sixword::InputError
41
+ #
42
+ # @see Sixword.encode_iter
43
+ #
44
+ # @example
45
+ # >> Sixword.encode('Hi world')
46
+ # => ["ACRE", "ADEN", "INN", "SLID", "MAD", "PAP"]
47
+ #
16
48
  def self.encode(byte_string)
17
- encode_to_a(byte_string)
49
+ encode_iter(byte_string).to_a
18
50
  end
19
51
 
52
+ # Encode a string of bytes in six-word encoding, using the custom padding
53
+ # scheme established by this library. The output will be identical to
54
+ # {Sixword.encode} for strings that are a multiple of 8 in length.
55
+ #
56
+ # @param byte_string [String] A string of any length
57
+ # @return [Array<String>] an array of string words
58
+ #
59
+ # @see Sixword.encode_iter
60
+ #
61
+ # @example
62
+ # >> Sixword.encode('Hi wor')
63
+ # => ["ACRE", "ADEN", "INN", "SLID", "MAD", "PAP"]
64
+ #
20
65
  def self.pad_encode(byte_string)
21
- pad_encode_to_a(byte_string)
66
+ encode_iter(byte_string, words_per_slice:1, pad:true).to_a
22
67
  end
23
68
 
69
+ # aliases for clarity on what the default encode(), pad_encode() return
70
+ class << self
71
+ alias_method :encode_to_a, :encode
72
+ alias_method :pad_encode_to_a, :pad_encode
73
+ end
74
+
75
+ # Like {Sixword.encode}, but return six words at a time (a complete block).
76
+ #
77
+ # @param byte_string [String] Length must be a multiple of 8
78
+ # @return [Array<String>] an array of 6-word string sentences
79
+ #
80
+ # @raise Sixword::InputError
81
+ #
82
+ # @example
83
+ # Sixword.encode_to_sentences('Hi world' * 2)
84
+ # => ["ACRE ADEN INN SLID MAD PAP",
85
+ # "ACRE ADEN INN SLID MAD PAP"]
86
+ #
87
+ # @see Sixword.encode
88
+ #
24
89
  def self.encode_to_sentences(byte_string)
25
90
  encode_iter(byte_string, words_per_slice:6).to_a
26
91
  end
27
92
 
93
+ # Like {Sixword.encode}, but return a single string.
94
+ #
95
+ # @param byte_string [String] Length must be a multiple of 8
96
+ # @return [String] a string of words separated by spaces
97
+ #
98
+ # @raise Sixword::InputError
99
+ #
100
+ # @example
101
+ # Sixword.encode_to_s('Hi world' * 2)
102
+ # => "ACRE ADEN INN SLID MAD PAP ACRE ADEN INN SLID MAD PAP"
103
+ #
104
+ # @see Sixword.encode
105
+ #
28
106
  def self.encode_to_s(byte_string)
29
107
  encode(byte_string).join(' ')
30
108
  end
31
109
 
32
- def self.encode_to_a(byte_string)
33
- encode_iter(byte_string).to_a
34
- end
35
-
36
- def self.pad_encode_to_a(byte_string)
37
- encode_iter(byte_string, words_per_slice:1, pad:true).to_a
38
- end
39
-
110
+ # Like {Sixword.encode_to_sentences}, but allow variable length input.
111
+ #
112
+ # @param byte_string [String] A string of any length
113
+ # @return [Array<String>] an array of 6-word string sentences
114
+ #
115
+ # @example
116
+ # >> Sixword.pad_encode_to_sentences('Hi worl' * 2)
117
+ # => ["ACRE ADEN INN SLID MAD LEW", "CODY AS SIGH SUIT MUDD ABE2"]
118
+ #
40
119
  def self.pad_encode_to_sentences(byte_string)
41
120
  encode_iter(byte_string, words_per_slice:6, pad:true).to_a
42
121
  end
43
122
 
123
+ # Like {Sixword.encode_to_s}, but allow variable length input.
124
+ #
125
+ # @param byte_string [String] A string of any length
126
+ # @return [String] a string of words separated by spaces
127
+ #
128
+ # @example
129
+ # >> Sixword.pad_encode_to_s('Hi worl' * 2)
130
+ # => "ACRE ADEN INN SLID MAD LEW CODY AS SIGH SUIT MUDD ABE2"
131
+ #
132
+ def self.pad_encode_to_s(byte_string)
133
+ pad_encode(byte_string).join(' ')
134
+ end
135
+
136
+ # Encode a string of bytes in six-word encoding (full API). This is the
137
+ # relatively low level method that supports all the major options. See the
138
+ # various other top-level methods for convenience helpers.
139
+ #
140
+ # @param byte_string [String] A byte string to encode
141
+ # @param options [Hash]
142
+ #
143
+ # @option options [Boolean] :pad (false) Whether to use the custom padding
144
+ # scheme established by this library. If false, then byte_string length
145
+ # must be a multiple of 8.
146
+ # @option options [Integer] :words_per_slice (1) The number of words to
147
+ # yield together in each iteration. By default, yield only a single word at
148
+ # a time. You can yield up to 6 words together, which will be joined by a
149
+ # space ` ` character.
150
+ #
151
+ # @yield [String] A String word (or String of space separated words, if
152
+ # :words_per_slice is given)
153
+ #
154
+ # @return [Enumerator, nil] If no block is given, return an Enumerator
155
+ #
156
+ # @raise Sixword::InputError on incorrectly padded inputs
157
+ # @raise ArgumentError on bad argument types
158
+ #
44
159
  def self.encode_iter(byte_string, options={})
45
160
  options = {words_per_slice: 1, pad: false}.merge(options)
46
161
  words_per_slice = options.fetch(:words_per_slice)
@@ -51,7 +166,7 @@ module Sixword
51
166
  end
52
167
 
53
168
  unless block_given?
54
- return Enumerator.new(self, :encode_iter, byte_string, options)
169
+ return to_enum(__method__, byte_string, options)
55
170
  end
56
171
 
57
172
  if !pad && byte_string.bytesize % 8 != 0
@@ -87,6 +202,39 @@ module Sixword
87
202
  end
88
203
  end
89
204
 
205
+ # Decode a six-word encoded string or string array.
206
+ #
207
+ # @param string_or_words [String, Array<String>] Either a String containing
208
+ # whitespace separated words or an Array of String words
209
+ # @param options [Hash]
210
+ #
211
+ # @option options [Boolean] :padding_ok (false) Whether to accept the custom
212
+ # padding format established by this library
213
+ #
214
+ # @return [String] A binary string of bytes
215
+ #
216
+ # @raise InputError if the input is malformed or invalid in various ways
217
+ #
218
+ # @example
219
+ # >> Sixword.decode("ACRE ADEN INN SLID MAD PAP")
220
+ # => "Hi world"
221
+ #
222
+ # @example
223
+ # >> Sixword.decode("acre aden inn slid mad pap")
224
+ # => "Hi world"
225
+ #
226
+ # @example
227
+ # Sixword.decode(%w{ACRE ADEN INN SLID MAD PAP})
228
+ # => "Hi world"
229
+ #
230
+ # @example
231
+ # Sixword.decode([])
232
+ # => ""
233
+ #
234
+ # @example
235
+ # Sixword.decode("COAT ACHE A A A ACT6", padding_ok: true)
236
+ # => "hi"
237
+ #
90
238
  def self.decode(string_or_words, options={})
91
239
  options = {padding_ok: false}.merge(options)
92
240
  padding_ok = options.fetch(:padding_ok)
@@ -110,6 +258,21 @@ module Sixword
110
258
  bstring
111
259
  end
112
260
 
261
+ # Like {Sixword.decode}, but allow input to contain custom padding scheme.
262
+ #
263
+ # @see Sixword.decode
264
+ #
265
+ # @param string_or_words [String, Array<String>] Either a String containing
266
+ # whitespace separated words or an Array of String words
267
+ #
268
+ # @return [String] A binary string of bytes
269
+ #
270
+ # @raise InputError if the input is malformed or invalid in various ways
271
+ #
272
+ # @example
273
+ # Sixword.decode("COAT ACHE A A A ACT6", padding_ok: true)
274
+ # => "hi"
275
+ #
113
276
  def self.pad_decode(string_or_words)
114
277
  decode(string_or_words, padding_ok: true)
115
278
  end