fast_xor 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +7 -7
- data/benchmark +23 -0
- data/ext/xor/extconf.rb +2 -0
- data/ext/{xor.c → xor/xor.c} +14 -6
- data/spec/xor_spec.rb +40 -0
- metadata +65 -15
- data/Rakefile +0 -46
- data/rake/extensiontask.rb +0 -191
- data/test/benchmark.rb +0 -23
- data/test/test_xor.rb +0 -45
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= String XOR Ruby Extension
|
2
2
|
|
3
|
-
+fast_xor+ is a simple extension which provides fast in-place String XOR functions
|
3
|
+
+fast_xor+ is a simple extension which provides fast in-place String XOR functions, suitable for cryptography.
|
4
4
|
|
5
5
|
== How do you use it?
|
6
6
|
|
@@ -18,16 +18,16 @@
|
|
18
18
|
|
19
19
|
== How fast is "Fast"?
|
20
20
|
|
21
|
-
|
21
|
+
Almost 50,000x faster than pure Ruby, on my machine (your mileage my vary):
|
22
22
|
|
23
|
-
$
|
24
|
-
|
25
|
-
Ruby:
|
26
|
-
C
|
23
|
+
$ ./benchmark
|
24
|
+
user system total real
|
25
|
+
Ruby : 6.100000 0.010000 6.110000 ( 6.307756)
|
26
|
+
C (x1000): 0.140000 0.000000 0.140000 ( 0.144665)
|
27
27
|
|
28
28
|
|
29
29
|
Author:: Steve Sloan (mailto:steve@finagle.org)
|
30
30
|
Website:: http://github.com/CodeMonkeySteve/fast_xor
|
31
|
-
Copyright:: Copyright (c) 2009 Steve Sloan
|
31
|
+
Copyright:: Copyright (c) 2009-2010 Steve Sloan
|
32
32
|
License:: MIT
|
33
33
|
|
data/benchmark
ADDED
@@ -0,0 +1,23 @@
|
|
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
|
+
i = 0
|
9
|
+
other.each_byte.with_index { |b, i| self[i] = (self[i].ord ^ b).chr }
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'xor'
|
13
|
+
alias_method :fast_xor!, :xor!
|
14
|
+
end
|
15
|
+
|
16
|
+
a = ([255].pack('C')) * (2**17) # 128k
|
17
|
+
b = a.dup
|
18
|
+
n = (ARGV.first || 10).to_i
|
19
|
+
|
20
|
+
Benchmark.bm do |x|
|
21
|
+
x.report('Ruby :') do n.times { a.slow_xor! b } end
|
22
|
+
x.report('C (x1000):') do (n*1000).times { a.fast_xor! b } end
|
23
|
+
end
|
data/ext/xor/extconf.rb
ADDED
data/ext/{xor.c → xor/xor.c}
RENAMED
@@ -1,6 +1,14 @@
|
|
1
1
|
#include <stdio.h>
|
2
2
|
#include <ruby.h>
|
3
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
|
+
|
4
12
|
VALUE string_xor( int argc, VALUE *argv, VALUE self ) {
|
5
13
|
const char *src = 0;
|
6
14
|
char *dest = 0 ;
|
@@ -11,12 +19,12 @@ VALUE string_xor( int argc, VALUE *argv, VALUE self ) {
|
|
11
19
|
return Qnil;
|
12
20
|
}
|
13
21
|
|
14
|
-
dest =
|
15
|
-
length =
|
22
|
+
dest = RSTRING_PTR(self);
|
23
|
+
length = RSTRING_LEN(self);
|
16
24
|
|
17
25
|
if ( TYPE(argv[0]) == T_STRING ) {
|
18
|
-
src =
|
19
|
-
size_t l =
|
26
|
+
src = RSTRING_PTR(argv[0]);
|
27
|
+
size_t l = RSTRING_LEN(argv[0]);
|
20
28
|
if ( l < length )
|
21
29
|
length = l;
|
22
30
|
} else {
|
@@ -32,8 +40,8 @@ VALUE string_xor( int argc, VALUE *argv, VALUE self ) {
|
|
32
40
|
const char *src2 = 0;
|
33
41
|
|
34
42
|
if ( TYPE(argv[1]) == T_STRING ) {
|
35
|
-
src2 =
|
36
|
-
size_t l =
|
43
|
+
src2 = RSTRING_PTR(argv[1]);
|
44
|
+
size_t l = RSTRING_LEN(argv[1]);
|
37
45
|
if ( l < length )
|
38
46
|
length = l;
|
39
47
|
} else {
|
data/spec/xor_spec.rb
ADDED
@@ -0,0 +1,40 @@
|
|
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 'XORs two strings' 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 'XORs three strings' 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
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fast_xor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 1.1.0
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Steve Sloan
|
@@ -9,25 +14,65 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date:
|
17
|
+
date: 2010-10-29 00:00:00 -07:00
|
13
18
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rake
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
prerelease: false
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rake-compiler
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
segments:
|
41
|
+
- 0
|
42
|
+
version: "0"
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: *id002
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
segments:
|
54
|
+
- 2
|
55
|
+
- 0
|
56
|
+
- 1
|
57
|
+
version: 2.0.1
|
58
|
+
type: :development
|
59
|
+
prerelease: false
|
60
|
+
version_requirements: *id003
|
16
61
|
description: Provides a C-optimized method for in-place XORing of two (or three) strings
|
17
62
|
email: steve@finagle.org
|
18
63
|
executables: []
|
19
64
|
|
20
65
|
extensions:
|
21
|
-
-
|
66
|
+
- ext/xor/extconf.rb
|
22
67
|
extra_rdoc_files:
|
23
68
|
- README.rdoc
|
24
69
|
files:
|
25
70
|
- MIT-LICENSE
|
26
71
|
- README.rdoc
|
27
|
-
-
|
28
|
-
-
|
29
|
-
-
|
30
|
-
-
|
72
|
+
- benchmark
|
73
|
+
- ext/xor/xor.c
|
74
|
+
- ext/xor/extconf.rb
|
75
|
+
- spec/xor_spec.rb
|
31
76
|
has_rdoc: true
|
32
77
|
homepage: http://github.com/CodeMonkeySteve/fast_xor
|
33
78
|
licenses: []
|
@@ -36,26 +81,31 @@ post_install_message:
|
|
36
81
|
rdoc_options:
|
37
82
|
- --charset=UTF-8
|
38
83
|
require_paths:
|
39
|
-
-
|
84
|
+
- lib/fast_xor
|
40
85
|
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
41
87
|
requirements:
|
42
88
|
- - ">="
|
43
89
|
- !ruby/object:Gem::Version
|
90
|
+
hash: 1119320670912771159
|
91
|
+
segments:
|
92
|
+
- 0
|
44
93
|
version: "0"
|
45
|
-
version:
|
46
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
47
96
|
requirements:
|
48
97
|
- - ">="
|
49
98
|
- !ruby/object:Gem::Version
|
99
|
+
hash: 1119320670912771159
|
100
|
+
segments:
|
101
|
+
- 0
|
50
102
|
version: "0"
|
51
|
-
version:
|
52
103
|
requirements: []
|
53
104
|
|
54
105
|
rubyforge_project:
|
55
|
-
rubygems_version: 1.3.
|
106
|
+
rubygems_version: 1.3.7
|
56
107
|
signing_key:
|
57
108
|
specification_version: 3
|
58
109
|
summary: Fast String XOR operator
|
59
110
|
test_files:
|
60
|
-
-
|
61
|
-
- test/test_xor.rb
|
111
|
+
- spec/xor_spec.rb
|
data/Rakefile
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
require 'rake'
|
2
|
-
require 'rake/clean'
|
3
|
-
require 'rake/extensiontask'
|
4
|
-
require 'rake/testtask'
|
5
|
-
require 'jeweler'
|
6
|
-
|
7
|
-
namespace 'xor' do
|
8
|
-
desc "Build the XOR extension"
|
9
|
-
Rake::ExtensionTask.new :xor do |t|
|
10
|
-
t.dir = 'ext'
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
task :test => 'xor:xor'
|
15
|
-
Rake::TestTask.new do |t|
|
16
|
-
t.libs << 'ext'
|
17
|
-
t.test_files = FileList['test/test_*.rb']
|
18
|
-
t.verbose = true
|
19
|
-
end
|
20
|
-
|
21
|
-
task :all => ['xor:xor', :test]
|
22
|
-
task :default => :all
|
23
|
-
|
24
|
-
Jeweler::Tasks.new do |g|
|
25
|
-
g.name = 'fast_xor'
|
26
|
-
g.summary = 'Fast String XOR operator'
|
27
|
-
g.description = 'Provides a C-optimized method for in-place XORing of two (or three) strings'
|
28
|
-
g.email = 'steve@finagle.org'
|
29
|
-
g.homepage = 'http://github.com/CodeMonkeySteve/fast_xor'
|
30
|
-
g.authors = ['Steve Sloan']
|
31
|
-
|
32
|
-
g.files = %w(
|
33
|
-
README.rdoc MIT-LICENSE
|
34
|
-
rake/extensiontask.rb
|
35
|
-
ext/xor.c
|
36
|
-
test/test_xor.rb
|
37
|
-
test/benchmark.rb
|
38
|
-
)
|
39
|
-
g.extensions = ['Rakefile']
|
40
|
-
g.require_paths = %w(ext)
|
41
|
-
|
42
|
-
# g.has_rdoc = true
|
43
|
-
# g.rdoc_options = %w| --line-numbers --inline-source --main README.rdoc |
|
44
|
-
# g.extra_rdoc_files = %w| README.rdoc |
|
45
|
-
end
|
46
|
-
Jeweler::GemcutterTasks.new
|
data/rake/extensiontask.rb
DELETED
@@ -1,191 +0,0 @@
|
|
1
|
-
require 'rake'
|
2
|
-
require 'rake/clean'
|
3
|
-
require 'rake/tasklib'
|
4
|
-
|
5
|
-
# Rake tasks to build Ruby extensions
|
6
|
-
|
7
|
-
module Rake
|
8
|
-
|
9
|
-
# Create a build task that will generate a Ruby extension (e.g. .so) from one or more
|
10
|
-
# C (.c) or C++ (.cc, .cpp, .cxx) files, and is intended as a replcaement for mkmf.
|
11
|
-
# It determines platform-specific settings (e.g. file extensions, compiler flags, etc.)
|
12
|
-
# from rbconfig (note: examples assume *nix file extensions).
|
13
|
-
#
|
14
|
-
# *Note*: Strings vs Symbols
|
15
|
-
# In places where filenames are expected (e.g. lib_name and objs), Strings are used
|
16
|
-
# as verbatim filenames, while, Symbols have the platform-dependant extension
|
17
|
-
# appended (e.g. '.so' for libraries and '.o' for objects). Also, only Symbols
|
18
|
-
# have #dir prepended to them.
|
19
|
-
#
|
20
|
-
# Example:
|
21
|
-
# desc "build sample extension"
|
22
|
-
# # build sample.so (from foo.{c,cc,cxx,cpp}, through foo.o)
|
23
|
-
# Rake::ExtensionTask.new :sample => :foo do |t|
|
24
|
-
# # all extension files under this directory
|
25
|
-
# t.dir = 'ext'
|
26
|
-
# # link libraries (libbar.so)
|
27
|
-
# t.link_libs << 'bar'
|
28
|
-
# end
|
29
|
-
#
|
30
|
-
# Author:: Steve Sloan (mailto:steve@finagle.org)
|
31
|
-
# Copyright:: Copyright (c) 2006 Steve Sloan
|
32
|
-
# License:: GPL
|
33
|
-
|
34
|
-
class ExtensionTask < Rake::TaskLib
|
35
|
-
# The name of the extension
|
36
|
-
attr_accessor :name
|
37
|
-
|
38
|
-
# The filename of the extension library file (e.g. 'extension.so')
|
39
|
-
attr_accessor :lib_name
|
40
|
-
|
41
|
-
# Object files to build and link into the extension.
|
42
|
-
attr_accessor :objs
|
43
|
-
|
44
|
-
# The directory where the extension files (source, output, and
|
45
|
-
# intermediate) are stored.
|
46
|
-
attr_accessor :dir
|
47
|
-
|
48
|
-
# Environment configuration -- i.e. CONFIG from rbconfig, with a few other
|
49
|
-
# settings, and converted to lowercase-symbols.
|
50
|
-
attr_accessor :env
|
51
|
-
|
52
|
-
# Additional link libraries
|
53
|
-
attr_accessor :link_libs
|
54
|
-
|
55
|
-
# Same arguments as Rake::define_task
|
56
|
-
def initialize( args, &blk )
|
57
|
-
@env = @@DefaultEnv.dup
|
58
|
-
@name, @objs = resolve_args(args)
|
59
|
-
set_defaults
|
60
|
-
yield self if block_given?
|
61
|
-
define_tasks
|
62
|
-
end
|
63
|
-
|
64
|
-
# Generate default values. This is called from initialize _before_ the
|
65
|
-
# yield block.
|
66
|
-
#
|
67
|
-
# Defaults:
|
68
|
-
# - lib_name: name.so
|
69
|
-
# - objs: name.o (<- name.{c,cxx,cpp,cc})
|
70
|
-
# - dir: .
|
71
|
-
# - link_libs: <none>
|
72
|
-
def set_defaults
|
73
|
-
@lib_name ||= name.to_sym
|
74
|
-
@objs = [name.to_sym] unless @objs and @objs.any?
|
75
|
-
@dir ||= '.'
|
76
|
-
@link_libs ||= []
|
77
|
-
end
|
78
|
-
|
79
|
-
# Defines the library task.
|
80
|
-
def define_tasks
|
81
|
-
output_objs = @objs.collect { |obj| filepath obj, :objext }
|
82
|
-
output_lib = filepath lib_name, :dlext
|
83
|
-
|
84
|
-
task name => output_lib
|
85
|
-
|
86
|
-
file output_lib => output_objs do |t|
|
87
|
-
sh_cmd :ldshared, :dldflags, :ldflags,
|
88
|
-
{'-L' => :libdirs}, '-o', output_lib,
|
89
|
-
output_objs.join(' '),
|
90
|
-
link_libs.join(' '),
|
91
|
-
:libs, :dldlibs, :librubyarg_shared
|
92
|
-
end
|
93
|
-
|
94
|
-
CLEAN.include output_objs
|
95
|
-
CLOBBER.include output_lib
|
96
|
-
define_rules
|
97
|
-
end
|
98
|
-
|
99
|
-
# Defines C and C++ source-to-object rules, using the source extensions from env.
|
100
|
-
def define_rules
|
101
|
-
for ext in env[:c_exts]
|
102
|
-
Rake::Task.create_rule '.'+env[:objext] => '.'+ext do |r|
|
103
|
-
sh_cmd :cc, :cflags, :cppflags, {'-D' => :defines}, {'-I' => :includedirs}, {'-I' => :topdir},
|
104
|
-
'-c', '-o', r.name, r.sources
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
for ext in env[:cpp_exts]
|
109
|
-
Rake::Task.create_rule '.'+env[:objext] => '.'+ext do |r|
|
110
|
-
sh_cmd :cxx, :cxxflags, :cppflags, {'-D' => :defines}, {'-I' => :includedirs}, {'-I' => :topdir},
|
111
|
-
'-o', r.name, '-c', r.sources
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
class << self
|
117
|
-
# The default environment for all extensions.
|
118
|
-
@@DefaultEnv = {}
|
119
|
-
def env
|
120
|
-
@@DefaultEnv
|
121
|
-
end
|
122
|
-
def env=(e)
|
123
|
-
@@DefaultEnv = e
|
124
|
-
end
|
125
|
-
|
126
|
-
Config::CONFIG.merge(ENV).each { |k, v| @@DefaultEnv[k.downcase.to_sym] = v }
|
127
|
-
@@DefaultEnv = {
|
128
|
-
:cxx => 'c++',
|
129
|
-
:cxxflags => '',
|
130
|
-
:c_exts => ['c'],
|
131
|
-
:cpp_exts => ['cc', 'cxx', 'cpp'],
|
132
|
-
:includedirs => [],
|
133
|
-
:libdirs => [],
|
134
|
-
}.update(@@DefaultEnv)
|
135
|
-
end
|
136
|
-
|
137
|
-
protected
|
138
|
-
|
139
|
-
# Handles convenience filenames:
|
140
|
-
# * f (String) => f
|
141
|
-
# * f (Symbol) => dir/f.ext
|
142
|
-
def filepath( f, ext )
|
143
|
-
ext = env[ext] if Symbol === ext
|
144
|
-
Symbol === f ? File.join( dir, "#{f}.#{ext}" ) : f
|
145
|
-
end
|
146
|
-
|
147
|
-
# Convenience function for cnstructing command lines for build tools.
|
148
|
-
def optify( *opts )
|
149
|
-
return optify(*opts.first) if opts.size == 1 and opts.first.kind_of? Array
|
150
|
-
opts.collect do |opt|
|
151
|
-
case opt
|
152
|
-
when String then opt
|
153
|
-
when Symbol then optify env[opt]
|
154
|
-
when Hash
|
155
|
-
opt.collect do |k, v|
|
156
|
-
v = env[v] if v.kind_of? Symbol
|
157
|
-
if v.kind_of? Array
|
158
|
-
optify v.collect { |w| k.to_s + w.to_s }
|
159
|
-
elsif v
|
160
|
-
k.to_s + v.to_s
|
161
|
-
end
|
162
|
-
end
|
163
|
-
else
|
164
|
-
opt.to_s
|
165
|
-
end
|
166
|
-
end.join(' ').squeeze(' ')
|
167
|
-
end
|
168
|
-
|
169
|
-
def sh_cmd( cmd, *opts )
|
170
|
-
sh optify( cmd, *opts )
|
171
|
-
end
|
172
|
-
|
173
|
-
# For some reason, Rake::TaskManager.resolve_args can't be found, so snarf it.
|
174
|
-
def resolve_args(args)
|
175
|
-
case args
|
176
|
-
when Hash
|
177
|
-
fail "Too Many Task Names: #{args.keys.join(' ')}" if args.size > 1
|
178
|
-
fail "No Task Name Given" if args.size < 1
|
179
|
-
task_name = args.keys[0]
|
180
|
-
deps = args[task_name]
|
181
|
-
deps = [deps] if (String===deps) || (Regexp===deps) || (Proc===deps)
|
182
|
-
else
|
183
|
-
task_name = args
|
184
|
-
deps = []
|
185
|
-
end
|
186
|
-
[task_name, deps]
|
187
|
-
end
|
188
|
-
|
189
|
-
end
|
190
|
-
|
191
|
-
end
|
data/test/benchmark.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
$: << File.dirname($0) + '/../ext'
|
3
|
-
require 'benchmark'
|
4
|
-
|
5
|
-
class String
|
6
|
-
def slow_xor!(other)
|
7
|
-
i = 0
|
8
|
-
other.each_byte { |b| self[i] ^= b ; i += 1 }
|
9
|
-
end
|
10
|
-
|
11
|
-
require 'xor'
|
12
|
-
alias_method :fast_xor!, :xor!
|
13
|
-
end
|
14
|
-
|
15
|
-
a = ([255].pack('C')) * (2**17) # 128k
|
16
|
-
b = a.dup
|
17
|
-
|
18
|
-
n = 10
|
19
|
-
Benchmark.bm do |x|
|
20
|
-
x.report('Ruby:') do n.times { a.slow_xor! b } end
|
21
|
-
x.report('C :') do n.times { a.fast_xor! b } end
|
22
|
-
end
|
23
|
-
|
data/test/test_xor.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'xor'
|
3
|
-
|
4
|
-
class XORTest < Test::Unit::TestCase
|
5
|
-
def setup
|
6
|
-
@len = 16
|
7
|
-
@zero = [0x00].pack('C') * @len
|
8
|
-
@one = [0xFF].pack('C') * @len
|
9
|
-
@x = (0...@len).collect { rand 256 }.pack('C*')
|
10
|
-
@invx = (0...@len).collect { |i| @x[i] ^ 0xFF }.pack('C*')
|
11
|
-
end
|
12
|
-
|
13
|
-
def assert_equal( a, b )
|
14
|
-
super a.unpack('H*'), b.unpack('H*')
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_xor_same
|
18
|
-
assert_equal @zero, @x.dup.xor!(@x)
|
19
|
-
assert_equal @one, @x.dup.xor!(@invx)
|
20
|
-
assert_equal @x, @x.dup.xor!(@zero)
|
21
|
-
assert_equal @invx, @x.dup.xor!(@one)
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_xor2_same
|
25
|
-
assert_equal @x, @x.dup.xor!(@x, @x)
|
26
|
-
assert_equal @invx, @x.dup.xor!(@x, @invx)
|
27
|
-
assert_equal @zero, @x.dup.xor!(@x, @zero)
|
28
|
-
assert_equal @one, @x.dup.xor!(@x, @one)
|
29
|
-
|
30
|
-
assert_equal @invx, @x.dup.xor!(@invx, @x)
|
31
|
-
assert_equal @x, @x.dup.xor!(@invx, @invx)
|
32
|
-
assert_equal @one, @x.dup.xor!(@invx, @zero)
|
33
|
-
assert_equal @zero, @x.dup.xor!(@invx, @one)
|
34
|
-
|
35
|
-
assert_equal @zero, @x.dup.xor!(@zero, @x)
|
36
|
-
assert_equal @one, @x.dup.xor!(@zero, @invx)
|
37
|
-
assert_equal @invx, @x.dup.xor!(@zero, @one)
|
38
|
-
assert_equal @x, @x.dup.xor!(@zero, @zero)
|
39
|
-
|
40
|
-
assert_equal @one, @x.dup.xor!(@one, @x)
|
41
|
-
assert_equal @zero, @x.dup.xor!(@one, @invx)
|
42
|
-
assert_equal @invx, @x.dup.xor!(@one, @zero)
|
43
|
-
assert_equal @x, @x.dup.xor!(@one, @one)
|
44
|
-
end
|
45
|
-
end
|