xorcist 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 793234244f107edb7c72b40c9781eb02e9764a57
4
+ data.tar.gz: aeeaf63a70d085e9900d4023feb461b2e8a13518
5
+ SHA512:
6
+ metadata.gz: dbf415060c191c8cca73230f9e78af36ef5a8e1e14fb3adb777ca8fd86fc18d590666ab2187356bd4b7d6d6394babbea90979302581d8ecd2453a27d48a0bdb1
7
+ data.tar.gz: bbe34eed87957f7144e5962330d42ffcc611927f353075d09854670accef29fc26a563b9e8125abb631b9c1ca184089d6d43343bf2e37fb4f3956c65cd4508c7
@@ -0,0 +1,104 @@
1
+ # Xorcist :ghost:
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/xorcist.svg)](http://badge.fury.io/rb/xorcist)
4
+ [![Build Status](https://travis-ci.org/fny/xorcist.svg?branch=master)](https://travis-ci.org/fny/xorcist)
5
+
6
+ Blazing-fast-cross-platform-monkey-patch-free string XOR. Yes, that means JRuby too.
7
+
8
+ ## Usage
9
+
10
+ ```ruby
11
+ require 'xorcist'
12
+
13
+ a, b = 'a', 'b'
14
+ Xorcist.xor(a, b)
15
+ Xorcist.xor!(a, b)
16
+ ```
17
+
18
+ You can `include Xorcist` to expose its methods:
19
+
20
+ ```ruby
21
+ require 'xorcist'
22
+ include Xorcist
23
+
24
+ a, b = 'a', 'b'
25
+ xor(a, b)
26
+ xor!(a, b)
27
+ ```
28
+
29
+ Refinements on `String` are also available:
30
+
31
+ ```ruby
32
+ require 'xorcist'
33
+ require 'xorcist/refinements'
34
+ using Xorcist::Refinements
35
+
36
+ a, b = 'a', 'b'
37
+ a.xor(b)
38
+ a.xor!(b)
39
+ ```
40
+
41
+ You can also monkey patch `String` if you're into that:
42
+
43
+ ```ruby
44
+ require 'xorcist'
45
+ require 'xorcist/string_methods'
46
+ String.include(Xorcist::StringMethods)
47
+ ```
48
+
49
+ ## Benchmarks
50
+
51
+ Disclaimer: these are run from my craptop. Run 'em yourself with `bin/benchmark`.
52
+
53
+ ### MRI 2.2.1
54
+
55
+ ```
56
+ Calculating -------------------------------------
57
+ ruby 11.136k i/100ms
58
+ xorcist 71.472k i/100ms
59
+ -------------------------------------------------
60
+ ruby 144.198k (± 1.3%) i/s - 723.840k
61
+ xorcist 2.155M (± 0.7%) i/s - 10.792M
62
+ ```
63
+
64
+ ### JRuby 1.7.19
65
+
66
+ ```
67
+ Calculating -------------------------------------
68
+ ruby 142.000 i/100ms
69
+ xorcist 88.006k i/100ms
70
+ -------------------------------------------------
71
+ ruby 3.113k (±32.6%) i/s - 11.218k in 5.781000s
72
+ xorcist 3.184M (±32.9%) i/s - 12.321M
73
+ ```
74
+
75
+ ## Installation
76
+
77
+ Add this line to your application's Gemfile:
78
+
79
+ ```ruby
80
+ gem 'xorcist'
81
+ ```
82
+
83
+ And then execute:
84
+
85
+ $ bundle
86
+
87
+ Or install it yourself as:
88
+
89
+ $ gem install xorcist
90
+
91
+ ## Contributing
92
+
93
+ Bug reports and pull requests are welcome on GitHub at https://github.com/fny/xorcist. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
94
+
95
+ ## License
96
+
97
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
98
+
99
+ ## Special Thanks To...
100
+
101
+ - [Steve Sloan][http://www.finagle.org] for his [fast_xor gem][https://github.com/CodeMonkeySteve/fast_xor] from which most of the tests are borrowed
102
+ - [James Coglan][http://jcoglan.com] for his [guide on writing a JRuby Java extension][https://blog.jcoglan.com/2012/08/02/your-first-ruby-native-extension-java/]
103
+ - To all [contributers](https://github.com/fny/xorcist/graphs/contributors)! :beers:
104
+
@@ -0,0 +1,22 @@
1
+ import org.jruby.anno.JRubyMethod;
2
+ import org.jruby.runtime.ThreadContext;
3
+ import org.jruby.runtime.builtin.IRubyObject;
4
+ import org.jruby.RubyString;
5
+ import org.jruby.util.ByteList;
6
+
7
+ public class Xorcist {
8
+ @JRubyMethod(name = "xor!", module = true)
9
+ public static RubyString xorInPlace(ThreadContext context, IRubyObject self, RubyString x, RubyString y) {
10
+ byte[] xBytes = x.getBytes();
11
+ byte[] yBytes = y.getBytes();
12
+
13
+ int length = yBytes.length < xBytes.length ? yBytes.length : xBytes.length;
14
+
15
+ for(int i = 0; i < length; i++) {
16
+ xBytes[i] = (byte) (xBytes[i] ^ yBytes[i]);
17
+ }
18
+
19
+ x.setValue(new ByteList(xBytes));
20
+ return x;
21
+ }
22
+ }
@@ -0,0 +1,14 @@
1
+ import java.io.IOException;
2
+
3
+ import org.jruby.Ruby;
4
+ import org.jruby.RubyModule;
5
+ import org.jruby.runtime.load.BasicLibraryService;
6
+
7
+ public class XorcistService implements BasicLibraryService {
8
+ @Override
9
+ public boolean basicLoad(final Ruby runtime) throws IOException {
10
+ RubyModule xorcist = runtime.defineModule("Xorcist");
11
+ xorcist.defineAnnotatedMethods(Xorcist.class);
12
+ return true;
13
+ }
14
+ }
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+ extension_name = 'xorcist'
3
+ dir_config(extension_name)
4
+ create_makefile(extension_name)
@@ -0,0 +1,36 @@
1
+ #include "ruby.h"
2
+
3
+ VALUE Xorcist = Qnil;
4
+
5
+ void Init_xorcist();
6
+
7
+ VALUE xor_in_place(VALUE x, VALUE y, VALUE self);
8
+
9
+ VALUE xor_in_place(VALUE self, VALUE x, VALUE y) {
10
+ const char *src = 0;
11
+ char *dest = 0;
12
+ size_t len;
13
+ size_t y_len;
14
+
15
+ rb_str_modify(x);
16
+ dest = RSTRING_PTR(x);
17
+ len = RSTRING_LEN(x);
18
+
19
+ src = RSTRING_PTR(y);
20
+ y_len = RSTRING_LEN(y);
21
+
22
+ if (y_len < len) {
23
+ len = y_len;
24
+ }
25
+
26
+ for (; len--; ++dest, ++src) {
27
+ *dest ^= *src;
28
+ }
29
+
30
+ return x;
31
+ }
32
+
33
+ void Init_xorcist() {
34
+ Xorcist = rb_define_module("Xorcist");
35
+ rb_define_module_function(Xorcist, "xor!", xor_in_place, 2);
36
+ }
@@ -0,0 +1,15 @@
1
+ require 'xorcist/version'
2
+
3
+ if RUBY_ENGINE == 'jruby'
4
+ require 'jruby'
5
+ require File.expand_path('../xorcist.jar', __FILE__)
6
+ else
7
+ require File.expand_path('../xorcist.so', __FILE__)
8
+ end
9
+
10
+ module Xorcist
11
+ module_function
12
+ def xor(x, y)
13
+ xor!(x.dup, y)
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ require 'xorcist/string_methods'
2
+
3
+ module Xorcist
4
+ module Refinements
5
+ refine String do
6
+ include Xorcist::StringMethods
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Xorcist
2
+ module StringMethods
3
+ def xor(other)
4
+ Xorcist.xor(self, other)
5
+ end
6
+
7
+ def xor!(other)
8
+ Xorcist.xor!(self, other)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Xorcist
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+
3
+ if RUBY_ENGINE != 'jruby' && RUBY_ENGINE != 'rbx' && RUBY_VERSION >= '2.0.0'
4
+ require 'xorcist/refinements'
5
+
6
+ class RefinementsTest < Minitest::Test
7
+ using Xorcist::Refinements
8
+
9
+ def test_xor
10
+ assert_equal ZERO, X.xor(X)
11
+ assert_equal ONE, X.xor(INVX)
12
+ assert_equal X, X.xor(ZERO)
13
+ assert_equal INVX, X.xor(ONE)
14
+ end
15
+
16
+ def test_xor_in_place
17
+ a = "String"
18
+ b = a
19
+ b.xor!(X)
20
+ assert_equal(a, b)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ require 'xorcist'
2
+
3
+ require 'minitest'
4
+ require 'minitest/autorun'
5
+ require 'minitest/pride'
6
+
7
+ LEN = 16
8
+ ZERO = ([0x00].pack('C') * LEN).freeze
9
+ ONE = ([0xFF].pack('C') * LEN).freeze
10
+ X = (0...LEN).collect { rand 256 }.pack('C*').freeze
11
+ INVX = (0...LEN).collect { |i| X[i].ord ^ 0xFF }.pack('C*').freeze
@@ -0,0 +1,42 @@
1
+ require 'test_helper'
2
+
3
+ class XorcistTest < Minitest::Test
4
+ include Xorcist
5
+
6
+ def test_xor
7
+ assert_equal ZERO, xor(X, X)
8
+ assert_equal ONE, xor(X, INVX)
9
+ assert_equal X, xor(X, ZERO)
10
+ assert_equal INVX, xor(X, ONE)
11
+ end
12
+
13
+ def test_xor_in_place
14
+ a = "String"
15
+ b = a
16
+ xor!(b, X)
17
+ assert_equal(a, b)
18
+ end
19
+
20
+ #
21
+ # Tests for different string storage behaviors in MRI.
22
+ # See http://patshaughnessy.net/2012/1/4/never-create-ruby-strings-longer-than-23-characters
23
+ # for details.
24
+ # Might as well run them in other Rubies too.
25
+ #
26
+
27
+ def test_embedded_string
28
+ a = "Embedded string"
29
+ assert a.size <= 23
30
+ b = a.dup
31
+ xor!(b, X)
32
+ refute_equal(a, b)
33
+ end
34
+
35
+ def test_heap_string
36
+ a = "A very long string that's stored on the heap"
37
+ assert a.size > 24
38
+ b = a.dup
39
+ xor!(b, X*2)
40
+ refute_equal(a, b)
41
+ end
42
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xorcist
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Faraz Yashar
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 5.7.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 5.7.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake-compiler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Blazing-fast-cross-platform-monkey-patch-free string XOR. Yes, that means
70
+ JRuby too.
71
+ email:
72
+ - faraz.yashar@gmail.com
73
+ executables: []
74
+ extensions:
75
+ - ext/xorcist/extconf.rb
76
+ extra_rdoc_files: []
77
+ files:
78
+ - README.md
79
+ - ext/xorcist/Xorcist.java
80
+ - ext/xorcist/XorcistService.java
81
+ - ext/xorcist/extconf.rb
82
+ - ext/xorcist/xorcist.c
83
+ - lib/xorcist.rb
84
+ - lib/xorcist/refinements.rb
85
+ - lib/xorcist/string_methods.rb
86
+ - lib/xorcist/version.rb
87
+ - test/refinements_test.rb
88
+ - test/test_helper.rb
89
+ - test/xorcist_test.rb
90
+ homepage: https://github.com/fny/xorcist
91
+ licenses:
92
+ - MIT
93
+ metadata: {}
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 2.4.6
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: Blazing-fast-cross-platform-monkey-patch-free string XOR
114
+ test_files: []