├── .gitignore ├── Gemfile ├── Gemfile.lock ├── MIT-LICENSE ├── README.rdoc ├── Rakefile ├── benchmark ├── ext └── xor │ ├── extconf.rb │ └── xor.c ├── fast_xor.gemspec ├── lib └── .gemkeep └── spec └── xor_spec.rb /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .bundle 3 | public/.DS_Store 4 | .kdev4 5 | .rspec 6 | *.kdev4 7 | *.swp 8 | *.kate-swp 9 | pkg 10 | vendor/bundle 11 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gemspec 3 | 4 | gem 'byebug', :platform => :mri_20 5 | gem 'debugger', :platform => :mri_19 6 | gem 'ruby-debug', :platform => :mri_18 7 | 8 | gem 'guard-rspec' 9 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | fast_xor (1.1.3) 5 | rake 6 | rake-compiler 7 | 8 | GEM 9 | remote: https://rubygems.org/ 10 | specs: 11 | byebug (2.4.1) 12 | columnize (~> 0.3.6) 13 | debugger-linecache (~> 1.2.0) 14 | celluloid (0.15.2) 15 | timers (~> 1.1.0) 16 | coderay (1.1.0) 17 | columnize (0.3.6) 18 | debugger (1.6.3) 19 | columnize (>= 0.3.1) 20 | debugger-linecache (~> 1.2.0) 21 | debugger-ruby_core_source (~> 1.2.4) 22 | debugger-linecache (1.2.0) 23 | debugger-ruby_core_source (1.2.4) 24 | diff-lcs (1.2.5) 25 | ffi (1.11.1) 26 | formatador (0.2.4) 27 | guard (2.2.4) 28 | formatador (>= 0.2.4) 29 | listen (~> 2.1) 30 | lumberjack (~> 1.0) 31 | pry (>= 0.9.12) 32 | thor (>= 0.18.1) 33 | guard-rspec (4.2.0) 34 | guard (>= 2.1.1) 35 | rspec (>= 2.14, < 4.0) 36 | linecache (0.46) 37 | rbx-require-relative (> 0.0.4) 38 | listen (2.3.1) 39 | celluloid (>= 0.15.2) 40 | rb-fsevent (>= 0.9.3) 41 | rb-inotify (>= 0.9) 42 | lumberjack (1.0.4) 43 | method_source (0.8.2) 44 | pry (0.9.12.4) 45 | coderay (~> 1.0) 46 | method_source (~> 0.8) 47 | slop (~> 3.4) 48 | rake (13.0.0) 49 | rake-compiler (1.0.8) 50 | rake 51 | rb-fsevent (0.9.3) 52 | rb-inotify (0.9.2) 53 | ffi (>= 0.5.0) 54 | rbx-require-relative (0.0.9) 55 | rspec (2.14.1) 56 | rspec-core (~> 2.14.0) 57 | rspec-expectations (~> 2.14.0) 58 | rspec-mocks (~> 2.14.0) 59 | rspec-core (2.14.7) 60 | rspec-expectations (2.14.4) 61 | diff-lcs (>= 1.1.3, < 2.0) 62 | rspec-mocks (2.14.4) 63 | ruby-debug (0.10.4) 64 | columnize (>= 0.1) 65 | ruby-debug-base (~> 0.10.4.0) 66 | ruby-debug-base (0.10.4) 67 | linecache (>= 0.3) 68 | slop (3.4.7) 69 | thor (0.18.1) 70 | timers (1.1.0) 71 | 72 | PLATFORMS 73 | ruby 74 | 75 | DEPENDENCIES 76 | byebug 77 | debugger 78 | fast_xor! 79 | guard-rspec 80 | rspec 81 | ruby-debug 82 | -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006-2009 Steve Sloan 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | = THIS GEM IS DEPRECATED 2 | 3 | I recommend that you use the {xorcist}[https://github.com/fny/xorcist] gem instead, as it has more features and support. 4 | 5 | == String XOR Ruby Extension 6 | 7 | +fast_xor+ is a simple extension which provides fast in-place String XOR functions, suitable for cryptography. 8 | 9 | == How do you use it? 10 | 11 | require 'xor' 12 | 13 | # two-argument version 14 | a, b = 'a string', 'another string' 15 | a.xor!(b) 16 | a == "\000N\034\000\032\f\034G" 17 | 18 | # three-argument version 19 | a, b, c = 'a string', 'another string', 'yet another string' 20 | a.xor!(b, c) 21 | a == "y+h {bs3" 22 | 23 | == How fast is "Fast"? 24 | 25 | Over 5,000x faster than pure Ruby, on my machine (your mileage my vary): 26 | 27 | $ ./benchmark 28 | user system total real 29 | Ruby : 4.530000 0.000000 4.530000 ( 4.535203) 30 | C (x1000): 0.780000 0.000000 0.780000 ( 0.781100) 31 | 32 | 33 | Author:: Steve Sloan (mailto:steve@finagle.org) 34 | Website:: http://github.com/CodeMonkeySteve/fast_xor 35 | Copyright:: Copyright (c) 2009-2013 Steve Sloan 36 | License:: MIT 37 | 38 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | Bundler.setup 3 | 4 | require 'rake' 5 | require 'rake/extensiontask' 6 | require 'rubygems/package_task' 7 | require 'rspec/core/rake_task' 8 | 9 | gem = Gem::Specification.load( File.dirname(__FILE__) + '/fast_xor.gemspec' ) 10 | Rake::ExtensionTask.new( 'xor', gem ) 11 | 12 | Gem::PackageTask.new gem do |pkg| 13 | pkg.need_zip = pkg.need_tar = false 14 | end 15 | 16 | RSpec::Core::RakeTask.new :spec do |spec| 17 | spec.pattern = 'spec/**/*_spec.rb' 18 | end 19 | 20 | task :default => [:compile, :spec] 21 | 22 | -------------------------------------------------------------------------------- /benchmark: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | $: << File.dirname(__FILE__)+'/lib' 3 | require 'benchmark' 4 | require 'xor' 5 | 6 | class String 7 | def slow_xor!(other) 8 | s = '' 9 | other.each_byte.with_index { |b, i| s << (self[i].ord ^ b).chr } 10 | replace(s) 11 | end 12 | 13 | require 'xor' 14 | alias_method :fast_xor!, :xor! 15 | end 16 | 17 | a = ([255].pack('C')) * (2**17) # 128k 18 | b = a.dup 19 | n = (ARGV.first || 100).to_i 20 | 21 | Benchmark.bm do |x| 22 | x.report('Ruby :') do n.times { a.slow_xor! b } end 23 | x.report('C (x1000):') do (n*1000).times { a.fast_xor! b } end 24 | end 25 | -------------------------------------------------------------------------------- /ext/xor/extconf.rb: -------------------------------------------------------------------------------- 1 | require 'mkmf' 2 | create_makefile 'xor' 3 | -------------------------------------------------------------------------------- /ext/xor/xor.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* Backward compatibility with Ruby 1.8 */ 5 | #ifndef RSTRING_PTR 6 | #define RSTRING_PTR(s) (RSTRING(s)->ptr) 7 | #endif 8 | #ifndef RSTRING_LEN 9 | #define RSTRING_LEN(s) (RSTRING(s)->len) 10 | #endif 11 | 12 | VALUE string_xor( int argc, VALUE *argv, VALUE self ) { 13 | const char *src = 0; 14 | const char *src2 = 0; 15 | char *dest = 0 ; 16 | size_t length = 0; 17 | size_t l; 18 | 19 | if ( (argc < 1) || (argc > 2) ) { 20 | rb_raise( rb_eArgError, "wrong # of arguments(%d for 1 or 2)", argc ); 21 | return Qnil; 22 | } 23 | 24 | rb_str_modify(self); 25 | dest = RSTRING_PTR(self); 26 | length = RSTRING_LEN(self); 27 | 28 | if ( TYPE(argv[0]) == T_STRING ) { 29 | l = RSTRING_LEN(argv[0]); 30 | src = RSTRING_PTR(argv[0]); 31 | if ( l < length ) 32 | length = l; 33 | } else { 34 | rb_raise( rb_eTypeError, "in method '" "xor" "', argument " "1"" of type '" "String""'" ); 35 | return Qnil; 36 | } 37 | 38 | if ( argc == 1 ) { 39 | for ( ; length--; ++dest, ++src ) 40 | *dest ^= *src; 41 | 42 | } else { 43 | if ( TYPE(argv[1]) == T_STRING ) { 44 | l = RSTRING_LEN(argv[1]); 45 | src2 = RSTRING_PTR(argv[1]); 46 | if ( l < length ) 47 | length = l; 48 | } else { 49 | rb_raise( rb_eTypeError, "in method '" "xor" "', argument " "2"" of type '" "String""'" ); 50 | return Qnil; 51 | } 52 | 53 | for ( ; length--; ++dest, ++src, ++src2 ) 54 | *dest ^= *src ^ *src2; 55 | } 56 | 57 | return self; 58 | } 59 | 60 | 61 | void Init_xor( void ) 62 | { 63 | rb_define_method( rb_cString, "xor!", ((VALUE (*)(ANYARGS)) string_xor), -1 ); 64 | } 65 | -------------------------------------------------------------------------------- /fast_xor.gemspec: -------------------------------------------------------------------------------- 1 | Gem::Specification.new do |s| 2 | s.name = 'fast_xor' 3 | s.version = '1.1.3' 4 | s.date = '2013-12-05' 5 | s.summary = 'Fast String XOR operator' 6 | s.description = 'Provides a C-optimized method for in-place XORing of two (or three) strings' 7 | 8 | s.authors = ['Steve Sloan'] 9 | s.email = 'steve@finagle.org' 10 | s.homepage = 'http://github.com/CodeMonkeySteve/fast_xor' 11 | 12 | s.extensions = ['ext/xor/extconf.rb'] 13 | s.require_paths = ['lib'] 14 | s.files = [ 15 | 'MIT-LICENSE', 16 | 'README.rdoc', 17 | 'benchmark', 18 | 'lib/.gemkeep', 19 | 'ext/xor/xor.c', 20 | 'ext/xor/extconf.rb', 21 | ] 22 | s.test_files = Dir['spec/**/*_spec.rb'] 23 | 24 | s.extra_rdoc_files = ['README.rdoc'] 25 | s.rdoc_options = ['--charset=UTF-8'] 26 | 27 | s.platform = Gem::Platform::RUBY 28 | s.rubygems_version = '1.3.7' 29 | 30 | s.add_dependency 'rake' 31 | s.add_dependency 'rake-compiler' 32 | 33 | s.add_development_dependency 'rspec' 34 | 35 | s.rdoc_options = %w[ 36 | --exclude .*\.so 37 | ] 38 | end 39 | 40 | -------------------------------------------------------------------------------- /lib/.gemkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeMonkeySteve/fast_xor/b4ecc7394f789e4bb0f7d537ff2ac0dfd0ad4b47/lib/.gemkeep -------------------------------------------------------------------------------- /spec/xor_spec.rb: -------------------------------------------------------------------------------- 1 | require 'xor' 2 | 3 | describe String do 4 | before do 5 | @len = 16 6 | @zero = [0x00].pack('C') * @len 7 | @one = [0xFF].pack('C') * @len 8 | @x = (0...@len).collect { rand 256 }.pack('C*') 9 | @invx = (0...@len).collect { |i| @x[i].ord ^ 0xFF }.pack('C*') 10 | end 11 | 12 | it "two" do 13 | @x.dup.xor!(@x) .should == @zero 14 | @x.dup.xor!(@invx).should == @one 15 | @x.dup.xor!(@zero).should == @x 16 | @x.dup.xor!(@one) .should == @invx 17 | end 18 | 19 | it "three" do 20 | @x.dup.xor!(@x, @x) .should == @x 21 | @x.dup.xor!(@x, @invx).should == @invx 22 | @x.dup.xor!(@x, @zero).should == @zero 23 | @x.dup.xor!(@x, @one) .should == @one 24 | 25 | @x.dup.xor!(@invx, @x) .should == @invx 26 | @x.dup.xor!(@invx, @invx).should == @x 27 | @x.dup.xor!(@invx, @zero).should == @one 28 | @x.dup.xor!(@invx, @one) .should == @zero 29 | 30 | @x.dup.xor!(@zero, @x) .should == @zero 31 | @x.dup.xor!(@zero, @invx).should == @one 32 | @x.dup.xor!(@zero, @one) .should == @invx 33 | @x.dup.xor!(@zero, @zero).should == @x 34 | 35 | @x.dup.xor!(@one, @x) .should == @one 36 | @x.dup.xor!(@one, @invx).should == @zero 37 | @x.dup.xor!(@one, @zero).should == @invx 38 | @x.dup.xor!(@one, @one) .should == @x 39 | end 40 | 41 | it "shared" do 42 | a = 'string' 43 | b = a 44 | b.xor!(@x) 45 | b.should == a 46 | end 47 | 48 | it "embedded" do 49 | a = 'an embedded string' 50 | a.length.should <= 23 51 | 52 | b = a.dup 53 | b.xor!(@x) 54 | b.should_not == a 55 | end 56 | 57 | it "heap" do 58 | a = 'a very long string, stored on the heap' 59 | a.length.should > 24 60 | 61 | b = a.dup 62 | b.xor!(@x*2) 63 | b.should_not == a 64 | end 65 | end 66 | --------------------------------------------------------------------------------