id_pack 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e8731fab4947eaab425af39652bdb53123f64b66
4
+ data.tar.gz: 7f571ff94f358063908bf0c8f0d763431c2c5a87
5
+ SHA512:
6
+ metadata.gz: a9de58d8ce76c8f4aedcee05a7e0b2b7dac0838da532c8b7f90b23c347d16b3c9bc442a20110b7ec6635a7e117a0ae253c0339b045ace3a17188b2c201f2dac7
7
+ data.tar.gz: 7f81c9eef199e29ec689e0a632ade5b8fe536a2cfd11f9dfd02ca942b7ab10c562df01bd46249e8556467dc15d5bf313dc129d72e61a8827015eb12d7e172719
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.3
5
+ before_install: gem install bundler -v 1.15.1
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at ronald.tse@ribose.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in uuid_pack.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ id_pack (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.3)
10
+ rake (10.5.0)
11
+ rspec (3.6.0)
12
+ rspec-core (~> 3.6.0)
13
+ rspec-expectations (~> 3.6.0)
14
+ rspec-mocks (~> 3.6.0)
15
+ rspec-core (3.6.0)
16
+ rspec-support (~> 3.6.0)
17
+ rspec-expectations (3.6.0)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.6.0)
20
+ rspec-mocks (3.6.0)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.6.0)
23
+ rspec-support (3.6.0)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ bundler (~> 1.15)
30
+ id_pack!
31
+ rake (~> 10.0)
32
+ rspec (~> 3.6)
33
+
34
+ BUNDLED WITH
35
+ 1.16.0
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Ribose
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # IdPack
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/id_pack`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'id_pack'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install id_pack
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at
36
+ https://github.com/riboseinc/id_pack. This project is intended to be a safe,
37
+ welcoming space for collaboration, and contributors are expected to adhere to
38
+ the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
39
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,296 @@
1
+ /** vim: et:ts=2:sw=2:sts=2
2
+ * @license (c) 2017 Ribose Inc.
3
+ *
4
+ * IdPacker is a library provides encoding support for Number collections (Arrays or Objects).
5
+ *
6
+ *
7
+ * Usage:
8
+ *
9
+ * The encoding algorithm encodes a Number collection (in form of Array or Object) into another String.
10
+ *
11
+ * @param collection - Number collection (in form of Array or Object)
12
+ * @param windowSize - Maximunm length of the binary encodedString in binary form (default: 10)
13
+ * @param isExcludeNull - Exclude the object keys with null value (default: true)
14
+ * @param outputCharset - Control how the output look like. CANNOT CONTAIN DUPLICATED characters (default: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-")
15
+ *
16
+ * IdPacker.encodeHashKeys(collection, windowSize, isExcludeNull, outputCharset);
17
+ *
18
+ *
19
+ * Examples:
20
+ *
21
+ * // encrypt the items in an Array
22
+ * var collection = [5, 6, 21, 23, 25];
23
+ * IdPacker.encodeHashKeys(collection);
24
+ * => "_E~C_O.V"
25
+ *
26
+ * // encrypt the keys of an Object
27
+ * var collection = {
28
+ * 5: "a",
29
+ * 6: "b",
30
+ * 21: "c",
31
+ * 23: "d",
32
+ * 25: "e"
33
+ * };
34
+ * IdPacker.encodeHashKeys(collection);
35
+ * => "_E~C_O.V"
36
+ *
37
+ *
38
+ * The encoding algorithm:
39
+ *
40
+ * The algorithm first sorts the collection in ascending order. Then, it decomposes
41
+ * the sorted collection into multiple parts starting from 1. Finally, each part is
42
+ * encoded into one of the following three encodedString forms:
43
+ *
44
+ * 1) Spaces encodedString
45
+ * A encoded text with prefix '_', represents continuous space.
46
+ *
47
+ * 2) Range encodedString
48
+ * A encoded text with prefix '~', represents continuous number.
49
+ *
50
+ * 3) Binary encodedString
51
+ * A encoded text with prefix '.', represents arbitrary distributed numbers.
52
+ *
53
+ * In each part, the encodedString after the prefix is a value from a base-X number system, where
54
+ * X is the length of IdPacker.outputCharset (overridable).
55
+ *
56
+ * Take the encoded text "_E~C_O.V" (original collection: [5, 6, 21, 23, 25]) as an example.
57
+ * It consists of 4 parts:
58
+ *
59
+ * 1)_E
60
+ * 4 continuous space (0-4)
61
+ *
62
+ * 2) ~C
63
+ * 2 continuous number (5,6)
64
+ *
65
+ * 3) _O
66
+ * 14 continuous space (7-20)
67
+ *
68
+ * 4) .V
69
+ * Convert 'V' from the base-X number system to base-10 number system gives '21',
70
+ * convert '21' from the base-10 number system to base-2 (binary) number system gives '101'.
71
+ * '1' and '0' represent 'number' and 'space', respectively. Therefore, '101' denotes 21, 23, 25.
72
+ */
73
+ (function (factory) {
74
+ 'use strict';
75
+
76
+ /* AMD. Register as an anonymous module. */
77
+ if (typeof define === 'function' && define.amd) {
78
+ define(factory);
79
+ }
80
+
81
+ /* Node/CommonJS */
82
+ else if (typeof exports === 'object') {
83
+ module.exports = factory();
84
+ }
85
+
86
+ /* Browser globals */
87
+ else {
88
+ factory();
89
+ }
90
+
91
+ }(function() {
92
+ 'use strict';
93
+
94
+ return {
95
+ spacesEncodedStringPrefix: '_',
96
+ binaryEncodedStringPrefix: '.',
97
+ rangeEncodedStringPrefix: '~',
98
+ windowSize: 10,
99
+ isExcludeNull: true,
100
+ outputCharset: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-",
101
+
102
+ /**
103
+ * [1,2,3,6,7,8]
104
+ * => [IdPack.range(start: 1 length: 3), IdPack.range(start: 6 length: 3)]
105
+ */
106
+ convertNumbersToRanges: function (numbers) {
107
+ var ranges = [];
108
+ if (numbers.length > 0) {
109
+ var range = new IdPack.range(numbers[0], 1);
110
+ for (var i = 1; i < numbers.length; i++) {
111
+ if (numbers[i] == numbers[i-1]+1) {
112
+ range.length = range.length + 1;
113
+ } else {
114
+ ranges.push(range);
115
+ range = new IdPack.range(numbers[i], 1);
116
+ }
117
+ }
118
+ ranges.push(range);
119
+ }
120
+ return ranges;
121
+ },
122
+
123
+ /**
124
+ * [IdPack.range(start: 1 length: 3), IdPack.range(start: 6 length: 3)]
125
+ * => "11100111"
126
+ */
127
+ convertRangesToBinaryNumber: function (ranges) {
128
+ var binaryNumber = '';
129
+ var i, j;
130
+ for (i = 0; i < ranges.length; i++) {
131
+ if (i > 0) {
132
+ for (j = ranges[i].start; j > ranges[i-1].end() + 1; j--) {
133
+ binaryNumber += '0';
134
+ }
135
+ }
136
+ for (j = 0; j < ranges[i].length; j++) {
137
+ binaryNumber += '1';
138
+ }
139
+ }
140
+ return binaryNumber;
141
+ },
142
+
143
+ /**
144
+ * [5, 6, 21, 23, 25]
145
+ * => "_E~C_O.V"
146
+ */
147
+ encodeHashKeys: function(hash, windowSize, isExcludeNull, outputCharset) {
148
+ // set default values
149
+ windowSize = typeof windowSize === "number" ? windowSize : this.windowSize;
150
+ isExcludeNull = typeof isExcludeNull === "boolean" ? isExcludeNull : this.isExcludeNull;
151
+ outputCharset = typeof outputCharset === "string" ? outputCharset : this.outputCharset;
152
+
153
+ var encodedHashKeys = '';
154
+ var hashKeys = hash instanceof Array ? hash : [];
155
+
156
+ // convert keys in Object into array if collection is an Object
157
+ if (! (hash instanceof Array)) {
158
+ var hashKey;
159
+ for (hashKey in hash) {
160
+ if (!isExcludeNull || isExcludeNull && hash[hashKey]) {
161
+ hashKeys.push(parseInt(hashKey, 10));
162
+ }
163
+ }
164
+
165
+ if (! hashKeys.length) {
166
+ return '';
167
+ }
168
+ }
169
+
170
+ // sort the collection in ascending order
171
+ hashKeys.sort(function(a,b) {
172
+ return a - b;
173
+ });
174
+
175
+ var ranges = this.convertNumbersToRanges(hashKeys);
176
+ var prevEnd = 0;
177
+ var currStart = 1;
178
+ var spaces = 0;
179
+ var groupWithPrev = false;
180
+ var rangesToGroup = [];
181
+ var binaryNumber = '';
182
+ var decimalNumber = 0;
183
+ var encodedString = '';
184
+
185
+ for (var i = 0; i < ranges.length; i++) {
186
+
187
+ spaces = ranges[i].start - prevEnd;
188
+
189
+ if (groupWithPrev) {
190
+
191
+ if (ranges[i].end() - currStart + 1 == windowSize) {
192
+ rangesToGroup.push(ranges[i]);
193
+ binaryNumber = this.convertRangesToBinaryNumber(rangesToGroup);
194
+ decimalNumber = this.convertBinaryNumberToDecimalNumber(binaryNumber);
195
+ encodedString = this.binaryPrefix + this.encodeDecimalNumber(decimalNumber, outputCharset);
196
+ encodedHashKeys += encodedString;
197
+ rangesToGroup = [];
198
+ groupWithPrev = false;
199
+ } else if (ranges[i].end() - currStart + 1 >= windowSize) {
200
+
201
+ if (rangesToGroup.length == 1) {
202
+ encodedString = this.rangePrefix + this.encodeDecimalNumber(rangesToGroup[0].length, outputCharset);
203
+ encodedHashKeys += encodedString;
204
+ } else {
205
+ binaryNumber = this.convertRangesToBinaryNumber(rangesToGroup);
206
+ decimalNumber = this.convertBinaryNumberToDecimalNumber(binaryNumber);
207
+ encodedString = this.binaryPrefix + this.encodeDecimalNumber(decimalNumber, outputCharset);
208
+ encodedHashKeys += encodedString;
209
+ }
210
+
211
+ rangesToGroup = [];
212
+ encodedString = this.spacesPrefix + this.encodeDecimalNumber(spaces, outputCharset);
213
+ encodedHashKeys += encodedString;
214
+
215
+ if (ranges[i].length >= windowSize) {
216
+ encodedString = this.rangePrefix + this.encodeDecimalNumber(ranges[i].length, outputCharset);
217
+ encodedHashKeys += encodedString;
218
+ groupWithPrev = false;
219
+ } else {
220
+ rangesToGroup.push(ranges[i]);
221
+ currStart = ranges[i].start;
222
+ groupWithPrev = true;
223
+ }
224
+ } else {
225
+ rangesToGroup.push(ranges[i]);
226
+ }
227
+ } else {
228
+ if (spaces >= 0) {
229
+ encodedString = this.spacesPrefix + this.encodeDecimalNumber(spaces, outputCharset);
230
+ encodedHashKeys += encodedString;
231
+ }
232
+ if (ranges[i].length >= windowSize) {
233
+ encodedString = this.rangePrefix + this.encodeDecimalNumber(ranges[i].length, outputCharset);
234
+ encodedHashKeys += encodedString;
235
+ } else {
236
+ rangesToGroup.push(ranges[i]);
237
+ currStart = ranges[i].start;
238
+ groupWithPrev = true;
239
+ }
240
+ }
241
+ prevEnd = ranges[i].end();
242
+ }
243
+
244
+ if (rangesToGroup.length == 1) {
245
+ encodedString = this.rangePrefix + this.encodeDecimalNumber(rangesToGroup[0].length, outputCharset);
246
+ encodedHashKeys += encodedString;
247
+ } else if (rangesToGroup.length > 0) {
248
+ binaryNumber = this.convertRangesToBinaryNumber(rangesToGroup);
249
+ decimalNumber = this.convertBinaryNumberToDecimalNumber(binaryNumber);
250
+ encodedString = this.binaryPrefix + this.encodeDecimalNumber(decimalNumber, outputCharset);
251
+ encodedHashKeys += encodedString;
252
+ }
253
+ return encodedHashKeys;
254
+ },
255
+
256
+ encodeInteger: function (n) {
257
+ return this.encodeDecimalNumber(n);
258
+ },
259
+
260
+ /**
261
+ * "10101"
262
+ * => 21
263
+ */
264
+ convertBinaryNumberToDecimalNumber: function(binaryNumber) {
265
+ var decimalNumber = 0;
266
+ for (var i = 0; i < binaryNumber.length; i++) {
267
+ decimalNumber = decimalNumber + Math.pow(2, binaryNumber.length - i - 1) * parseInt(binaryNumber.charAt(i), 10);
268
+ }
269
+ return decimalNumber;
270
+ },
271
+
272
+ /**
273
+ * 5
274
+ * => F"
275
+ */
276
+ encodeDecimalNumber: function(decimalNumber, outputCharset) {
277
+ if (typeof outputCharset == 'undefined' || outputCharset == null) {
278
+ outputCharset = this.outputCharset;
279
+ }
280
+ var encodedNumber = "";
281
+ var base = outputCharset.length;
282
+ var quotient = decimalNumber;
283
+ var remainder;
284
+ while (true) {
285
+ remainder = quotient % base;
286
+ encodedNumber = outputCharset.charAt(remainder) + encodedNumber;
287
+ quotient = (quotient - remainder) / base;
288
+ if (quotient == 0) {
289
+ break;
290
+ }
291
+ }
292
+ return encodedNumber;
293
+ }
294
+ };
295
+
296
+ }));