xorcist 1.0.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +104 -0
- data/ext/xorcist/Xorcist.java +22 -0
- data/ext/xorcist/XorcistService.java +14 -0
- data/ext/xorcist/extconf.rb +4 -0
- data/ext/xorcist/xorcist.c +36 -0
- data/lib/xorcist.jar +0 -0
- data/lib/xorcist.rb +15 -0
- data/lib/xorcist/refinements.rb +9 -0
- data/lib/xorcist/string_methods.rb +11 -0
- data/lib/xorcist/version.rb +3 -0
- data/test/refinements_test.rb +23 -0
- data/test/test_helper.rb +11 -0
- data/test/xorcist_test.rb +42 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 04bd83615c3ecb37774b18b88e159f458585658c
|
4
|
+
data.tar.gz: 074ce686948c516e4c3fddda714de029ae6d612e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 655eab50ca30c1e09f21c990bb096fc5b6301c6f67fa1f829e5a8478cd7e9f386fb533ede86f191fa14ad80bd18382070e6f95af2834e078aa1d1dc455152647
|
7
|
+
data.tar.gz: da4117f1799fc026ebe325d06d16053b9955a7432cf5e3fc95d443797e12bc536423b67e08ce85c4ce12be24571141e8e5fcb0ec04cb03da4274f8ef5bd2bda3
|
data/README.md
ADDED
@@ -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,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
|
+
}
|
data/lib/xorcist.jar
ADDED
Binary file
|
data/lib/xorcist.rb
ADDED
@@ -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,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
|
data/test/test_helper.rb
ADDED
@@ -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,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xorcist
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: java
|
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
|
+
version_requirements: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.10'
|
20
|
+
requirement: !ruby/object:Gem::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ~>
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: '1.10'
|
25
|
+
prerelease: false
|
26
|
+
type: :development
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 5.7.0
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ~>
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 5.7.0
|
39
|
+
prerelease: false
|
40
|
+
type: :development
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ~>
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '10.0'
|
53
|
+
prerelease: false
|
54
|
+
type: :development
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake-compiler
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
prerelease: false
|
68
|
+
type: :development
|
69
|
+
description: Blazing-fast-cross-platform-monkey-patch-free string XOR. Yes, that means JRuby too.
|
70
|
+
email:
|
71
|
+
- faraz.yashar@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- README.md
|
77
|
+
- ext/xorcist/Xorcist.java
|
78
|
+
- ext/xorcist/XorcistService.java
|
79
|
+
- ext/xorcist/extconf.rb
|
80
|
+
- ext/xorcist/xorcist.c
|
81
|
+
- lib/xorcist.jar
|
82
|
+
- lib/xorcist.rb
|
83
|
+
- lib/xorcist/refinements.rb
|
84
|
+
- lib/xorcist/string_methods.rb
|
85
|
+
- lib/xorcist/version.rb
|
86
|
+
- test/refinements_test.rb
|
87
|
+
- test/test_helper.rb
|
88
|
+
- test/xorcist_test.rb
|
89
|
+
homepage: https://github.com/fny/xorcist
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
metadata: {}
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - '>='
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 2.4.5
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: Blazing-fast-cross-platform-monkey-patch-free string XOR
|
113
|
+
test_files: []
|