russdeep 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/LICENSE ADDED
@@ -0,0 +1,16 @@
1
+ russdeep - Ruby language bindings for the 'libfuzzy' ssdeep library
2
+ Copyright (c) 2010 Eric Monti
3
+
4
+ This program is free software; you can redistribute it and/or
5
+ modify it under the terms of the GNU General Public License
6
+ as published by the Free Software Foundation; either version 2
7
+ of the License, or (at your option) any later version.
8
+
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU General Public License for more details.
13
+
14
+ You should have received a copy of the GNU General Public License
15
+ along with this program; if not, write to the Free Software
16
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
data/README.rdoc ADDED
@@ -0,0 +1,60 @@
1
+ = russdeep
2
+
3
+ Ruby language bindings for the ssdeep 'libfuzzy' library api. This API lets you do
4
+ fuzzy hash comparisons between files and arbitrary string buffers. Fuzzy
5
+ hashes are also known as context triggered piecewise hashes (CTPH).
6
+
7
+ See the ssdeep homepage for more information:
8
+ http://ssdeep.sourceforge.net
9
+
10
+ == Requirements
11
+
12
+ * ssdeep's libfuzzy - http://ssdeep.sourceforge.net
13
+ The latest version of ssdeep known to work with russdeep is 2.5.
14
+
15
+ == Installation
16
+
17
+ First ensure you have installed the ssdeep package and that libfuzzy is in your libpath.
18
+ Then...
19
+
20
+ === Gem
21
+
22
+ (sudo)? gem install russdeep
23
+
24
+ === rake
25
+
26
+ git clone https://github.com/emonti/russdeep.git
27
+ cd russdeep
28
+ rake compile
29
+
30
+ == Example
31
+
32
+ require "ssdeep"
33
+
34
+ data1 =<<__EOM__
35
+ Ruby language bindings for the ssdeep 'libfuzzy' library api. This API lets you do
36
+ fuzzy hash comparisons between files and arbitrary string buffers. Fuzzy
37
+ hashes are also known as context triggered piecewise hashes (CTPH).
38
+
39
+ See the ssdeep homepage for more information:
40
+ http://ssdeep.sourceforge.net
41
+ __EOM__
42
+
43
+
44
+ hash1 = Ssdeep.from_string(data1)
45
+ hash2 = Ssdeep.from_string(data1 + "a little extra")
46
+ hash3 = Ssdeep.from_string(data1.gsub("ssdeep", "fuzzy"))
47
+ hash4 = Ssdeep.from_file("/etc/hosts")
48
+ hash5 = File.open("/etc/hosts"){|f| Ssdeep.from_fileno(f.fileno)}
49
+
50
+ Ssdeep.compare(hash1, hash1) # => 100
51
+ Ssdeep.compare(hash1, hash2) # => 97
52
+ Ssdeep.compare(hash1, hash3) # => 88
53
+ Ssdeep.compare(hash1, hash4) # => 0
54
+ Ssdeep.compare(hash4, hash5) # => 100
55
+
56
+ == License
57
+
58
+ See LICENSE.txt
59
+
60
+ Copyright (c) 2011 Eric Monti. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/extensiontask'
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "russdeep"
9
+ gem.summary = %Q{Ruby bindings for libfuzzy (from ssdeep)}
10
+ gem.description = %Q{Ruby bindings for libfuzzy, a fuzzy hashing implementation included with the ssdeep utility}
11
+ gem.email = "esmonti@gmail.com"
12
+ gem.homepage = "http://github.com/emonti/russdeep"
13
+ gem.authors = ["Eric Monti"]
14
+ gem.add_development_dependency "rspec", ">= 1.2.9"
15
+ gem.add_development_dependency "ffi", ">= 0"
16
+
17
+ if RUBY_PLATFORM !~ /java/
18
+ gem.extensions = FileList['ext/**/extconf.rb']
19
+ end
20
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
21
+ end
22
+ Jeweler::GemcutterTasks.new
23
+ rescue LoadError
24
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
25
+ end
26
+
27
+ require 'spec/rake/spectask'
28
+ Spec::Rake::SpecTask.new(:spec) do |spec|
29
+ spec.libs << 'lib' << 'spec'
30
+ spec.spec_files = FileList['spec/ssdeep_spec.rb', 'spec/**/*_spec.rb'].uniq
31
+ end
32
+
33
+ if RUBY_PLATFORM !~ /java/
34
+ Rake::ExtensionTask.new("ssdeep_native")
35
+
36
+ CLEAN.include("lib/*.bundle")
37
+ CLEAN.include("lib/*.so")
38
+ CLEAN.include("tmp")
39
+
40
+ task :spec => :compile
41
+ end
42
+
43
+
44
+ #task :spec => :check_dependencies
45
+
46
+ task :default => :spec
47
+
48
+ require 'rake/rdoctask'
49
+ Rake::RDocTask.new do |rdoc|
50
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
51
+
52
+ rdoc.rdoc_dir = 'rdoc'
53
+ rdoc.title = "russdeep #{version}"
54
+ rdoc.rdoc_files.include('README*')
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
56
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,17 @@
1
+ require 'mkmf'
2
+ require 'rbconfig'
3
+
4
+ extension_name = "ssdeep_native"
5
+
6
+ dir_config(extension_name)
7
+
8
+ unless find_library("fuzzy", "fuzzy_hash_file", "/lib", "/usr/lib", "/usr/local/lib") and
9
+ find_library("fuzzy", "fuzzy_hash_filename", "/lib", "/usr/lib", "/usr/local/lib") and
10
+ find_library("fuzzy", "fuzzy_hash_buf", "/lib", "/usr/lib", "/usr/local/lib") and
11
+ find_library("fuzzy", "fuzzy_compare", "/lib", "/usr/lib", "/usr/local/lib") and
12
+ find_header("fuzzy.h", "/lib", "/usr/lib", "/usr/local/include")
13
+ raise "You must install the ssdeep package"
14
+ end
15
+
16
+ create_makefile(extension_name)
17
+
@@ -0,0 +1,80 @@
1
+ #include "ruby.h"
2
+ #include <fuzzy.h>
3
+ #include <stdio.h>
4
+
5
+ static VALUE module_Ssdeep = Qnil;
6
+ static VALUE error_HashError = Qnil;
7
+
8
+ VALUE ssdeep_from_string(VALUE klass, VALUE buf) {
9
+ char hash[FUZZY_MAX_RESULT];
10
+ int ret;
11
+ Check_Type(buf, T_STRING);
12
+
13
+ ret = fuzzy_hash_buf((unsigned char *) RSTRING_PTR(buf), RSTRING_LEN(buf), hash);
14
+ if (ret == 0)
15
+ return rb_str_new2(hash);
16
+ else
17
+ rb_raise(error_HashError, "An error occurred hashing a string: ret=%i", ret);
18
+ }
19
+
20
+ VALUE ssdeep_from_filename(VALUE klass, VALUE filename) {
21
+ char hash[FUZZY_MAX_RESULT];
22
+ int ret;
23
+ Check_Type(filename, T_STRING);
24
+
25
+ ret=fuzzy_hash_filename(RSTRING_PTR(filename), hash);
26
+ if (ret == 0)
27
+ return rb_str_new2(hash);
28
+ else
29
+ rb_raise(error_HashError, "An error occurred the file: %s -- ret=%i", RSTRING_PTR(filename), ret);
30
+ }
31
+
32
+ VALUE ssdeep_from_fileno(VALUE klass, VALUE fileno) {
33
+ char hash[FUZZY_MAX_RESULT];
34
+ int ret, fd;
35
+ FILE *file;
36
+
37
+ Check_Type(fileno, T_FIXNUM);
38
+
39
+ fd = FIX2INT(fileno);
40
+
41
+ if (!(file=fdopen(fd, "r"))) {
42
+ rb_sys_fail(0);
43
+ return Qnil;
44
+ }
45
+
46
+ ret=fuzzy_hash_file(file, hash);
47
+ if (ret == 0)
48
+ return rb_str_new2(hash);
49
+ else
50
+ rb_raise(error_HashError, "An error occurred the fileno: %i -- ret=%i", fd, ret);
51
+ }
52
+
53
+ VALUE ssdeep_compare(VALUE klass, VALUE sig1, VALUE sig2) {
54
+ int ret;
55
+
56
+ Check_Type(sig1, T_STRING);
57
+ Check_Type(sig2, T_STRING);
58
+
59
+ if (strncmp(RSTRING_PTR(sig1), RSTRING_PTR(sig2), FUZZY_MAX_RESULT) == 0)
60
+ return INT2NUM(100);
61
+ else if ( (ret=fuzzy_compare(RSTRING_PTR(sig1), RSTRING_PTR(sig2))) < 0)
62
+ rb_raise(error_HashError, "An error occurred comparing hashes");
63
+ else
64
+ return INT2NUM(ret);
65
+ }
66
+
67
+ void Init_ssdeep_native() {
68
+ module_Ssdeep = rb_define_module("Ssdeep");
69
+
70
+ error_HashError = rb_define_class_under(module_Ssdeep, "HashError", rb_eStandardError);
71
+
72
+ rb_define_singleton_method(module_Ssdeep, "from_string", ssdeep_from_string, 1);
73
+ rb_define_singleton_method(module_Ssdeep, "from_file", ssdeep_from_filename, 1);
74
+ rb_define_singleton_method(module_Ssdeep, "from_fileno", ssdeep_from_fileno, 1);
75
+ rb_define_singleton_method(module_Ssdeep, "compare", ssdeep_compare, 2);
76
+
77
+ rb_define_const(module_Ssdeep, "FUZZY_MAX_RESULT", INT2NUM(FUZZY_MAX_RESULT));
78
+ rb_define_const(module_Ssdeep, "SPAMSUM_LENGTH", INT2NUM(SPAMSUM_LENGTH));
79
+ }
80
+
data/lib/ffi/ssdeep.rb ADDED
@@ -0,0 +1,75 @@
1
+ begin
2
+ require 'rubygems'
3
+ rescue LoadError
4
+ end
5
+
6
+ require 'ffi'
7
+
8
+ module FFI
9
+ module Ssdeep
10
+ class HashError < StandardError
11
+ end
12
+
13
+ extend FFI::Library
14
+
15
+ ffi_lib 'fuzzy'
16
+
17
+ SPAMSUM_LENGTH = 64
18
+ FUZZY_MAX_RESULT = (SPAMSUM_LENGTH + (SPAMSUM_LENGTH/2 + 20))
19
+
20
+ typedef :pointer, :fuzzy_hash
21
+
22
+ attach_function :fuzzy_hash_buf, [:pointer, :uint32, :fuzzy_hash], :int
23
+ attach_function :fuzzy_hash_file, [:pointer, :fuzzy_hash], :int
24
+ attach_function :fuzzy_hash_filename, [:string, :fuzzy_hash], :int
25
+ attach_function :fuzzy_compare, [:fuzzy_hash, :fuzzy_hash], :int
26
+
27
+ attach_function :fdopen, [:int, :string], :pointer
28
+
29
+
30
+ def self.from_string(buf)
31
+ bufp = FFI::MemoryPointer.new(buf.size)
32
+ bufp.write_string(buf)
33
+
34
+ out = FFI::MemoryPointer.new(FUZZY_MAX_RESULT)
35
+
36
+ if (ret=fuzzy_hash_buf(bufp, bufp.size, out)) == 0
37
+ return out.read_string
38
+ else
39
+ raise(HashError, "An error occurred hashing a string: ret=#{ret}")
40
+ end
41
+ end
42
+
43
+ def self.from_fileno(fileno)
44
+ if (not fileno.kind_of?(Integer)) or (file=fdopen(fileno, "r")).null?
45
+ raise(HashError, "Unable to open file descriptor: #{fileno}")
46
+ end
47
+
48
+ out = FFI::MemoryPointer.new(FUZZY_MAX_RESULT)
49
+
50
+ if (ret=fuzzy_hash_file(file, out)) == 0
51
+ return out.read_string
52
+ else
53
+ raise(HashError, "An error occurred hashing the file descriptor: #{fileno} -- ret=#{ret}")
54
+ end
55
+ end
56
+
57
+ def self.from_file(filename)
58
+ File.stat(filename)
59
+ out = FFI::MemoryPointer.new(FUZZY_MAX_RESULT)
60
+
61
+ if (ret=fuzzy_hash_filename(filename, out)) == 0
62
+ return out.read_string
63
+ else
64
+ raise(HashError, "An error occurred hashing the file: #{filename} -- ret=#{ret}");
65
+ end
66
+ end
67
+
68
+ def self.compare(sig1, sig2)
69
+ psig1 = FFI::MemoryPointer.from_string(sig1)
70
+ psig2 = FFI::MemoryPointer.from_string(sig2)
71
+
72
+ return fuzzy_compare(psig1, psig2)
73
+ end
74
+ end
75
+ end
data/lib/russdeep.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'ssdeep'
2
+
3
+ RuSsdeep = Ssdeep
data/lib/ssdeep.rb ADDED
@@ -0,0 +1,7 @@
1
+
2
+ if ENV['RUSSDEEP_USE_FFI'] or RUBY_PLATFORM =~ /java/
3
+ require 'ssdeep_ffi'
4
+ else
5
+ require 'ssdeep_native'
6
+ end
7
+
data/lib/ssdeep_ffi.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'ffi/ssdeep'
2
+
3
+ Ssdeep = FFI::Ssdeep
4
+
@@ -0,0 +1,24 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'ffi/ssdeep'
3
+
4
+ describe FFI::Ssdeep do
5
+ before(:all) {
6
+ @klass = FFI::Ssdeep
7
+ @f1 = sample_file("sample1.txt")
8
+ @f2 = sample_file("sample2.txt")
9
+
10
+ @f1_hash = '96:tQWAFF4IMtG6z4FEmYqGPUyukJM4kbqkTKL+LGw6b8f/EZMhJvybtSryfubB:tO4a68FZYqyG4w2+Bbzhpybg6u9'
11
+ @f2_hash = '192:sO4a68FZYqyG4w2+Bbzhpybg6uTI6l7yrnUxioPmSKx/A0IV2vRqtJUF2CnHqVC2:sOf6aYqyG4w3ug6uTI6lQUxioOLx/AZt'
12
+ }
13
+
14
+ it "should be using the FFI implementation" do
15
+ FFI::Ssdeep.should respond_to(:fuzzy_compare)
16
+ FFI::Ssdeep.should respond_to(:fuzzy_hash_file)
17
+ FFI::Ssdeep.should respond_to(:fuzzy_hash_filename)
18
+ FFI::Ssdeep.should respond_to(:fuzzy_hash_buf)
19
+ FFI::Ssdeep.should respond_to(:fdopen)
20
+ end
21
+
22
+ it_should_behave_like 'the Ssdeep interface'
23
+
24
+ end
@@ -0,0 +1,189 @@
1
+ SCENE I. A desert place.
2
+
3
+ Thunder and lightning. Enter three Witches
4
+
5
+ First Witch
6
+
7
+ When shall we three meet again
8
+ In thunder, lightning, or in rain?
9
+
10
+ Second Witch
11
+
12
+ When the hurlyburly's done,
13
+ When the battle's lost and won.
14
+
15
+ Third Witch
16
+
17
+ That will be ere the set of sun.
18
+
19
+ First Witch
20
+
21
+ Where the place?
22
+
23
+ Second Witch
24
+
25
+ Upon the heath.
26
+
27
+ Third Witch
28
+
29
+ There to meet with Macbeth.
30
+
31
+ First Witch
32
+
33
+ I come, Graymalkin!
34
+
35
+ Second Witch
36
+
37
+ Paddock calls.
38
+
39
+ Third Witch
40
+
41
+ Anon.
42
+
43
+ ALL
44
+
45
+ Fair is foul, and foul is fair:
46
+ Hover through the fog and filthy air.
47
+
48
+ Exeunt
49
+
50
+ SCENE II. A camp near Forres.
51
+
52
+ Alarum within. Enter DUNCAN, MALCOLM, DONALBAIN, LENNOX, with Attendants, meeting a bleeding Sergeant
53
+
54
+ DUNCAN
55
+
56
+ What bloody man is that? He can report,
57
+ As seemeth by his plight, of the revolt
58
+ The newest state.
59
+
60
+ MALCOLM
61
+
62
+ This is the sergeant
63
+ Who like a good and hardy soldier fought
64
+ 'Gainst my captivity. Hail, brave friend!
65
+ Say to the king the knowledge of the broil
66
+ As thou didst leave it.
67
+
68
+ Sergeant
69
+
70
+ Doubtful it stood;
71
+ As two spent swimmers, that do cling together
72
+ And choke their art. The merciless Macdonwald--
73
+ Worthy to be a rebel, for to that
74
+ The multiplying villanies of nature
75
+ Do swarm upon him--from the western isles
76
+ Of kerns and gallowglasses is supplied;
77
+ And fortune, on his damned quarrel smiling,
78
+ Show'd like a rebel's whore: but all's too weak:
79
+ For brave Macbeth--well he deserves that name--
80
+ Disdaining fortune, with his brandish'd steel,
81
+ Which smoked with bloody execution,
82
+ Like valour's minion carved out his passage
83
+ Till he faced the slave;
84
+ Which ne'er shook hands, nor bade farewell to him,
85
+ Till he unseam'd him from the nave to the chaps,
86
+ And fix'd his head upon our battlements.
87
+
88
+ DUNCAN
89
+
90
+ O valiant cousin! worthy gentleman!
91
+
92
+ Sergeant
93
+
94
+ As whence the sun 'gins his reflection
95
+ Shipwrecking storms and direful thunders break,
96
+ So from that spring whence comfort seem'd to come
97
+ Discomfort swells. Mark, king of Scotland, mark:
98
+ No sooner justice had with valour arm'd
99
+ Compell'd these skipping kerns to trust their heels,
100
+ But the Norweyan lord surveying vantage,
101
+ With furbish'd arms and new supplies of men
102
+ Began a fresh assault.
103
+
104
+ DUNCAN
105
+
106
+ Dismay'd not this
107
+ Our captains, Macbeth and Banquo?
108
+
109
+ Sergeant
110
+
111
+ Yes;
112
+ As sparrows eagles, or the hare the lion.
113
+ If I say sooth, I must report they were
114
+ As cannons overcharged with double cracks, so they
115
+ Doubly redoubled strokes upon the foe:
116
+ Except they meant to bathe in reeking wounds,
117
+ Or memorise another Golgotha,
118
+ I cannot tell.
119
+ But I am faint, my gashes cry for help.
120
+
121
+ DUNCAN
122
+
123
+ So well thy words become thee as thy wounds;
124
+ They smack of honour both. Go get him surgeons.
125
+
126
+ Exit Sergeant, attended
127
+ Who comes here?
128
+
129
+ Enter ROSS
130
+
131
+ MALCOLM
132
+
133
+ The worthy thane of Ross.
134
+
135
+ LENNOX
136
+
137
+ What a haste looks through his eyes! So should he look
138
+ That seems to speak things strange.
139
+
140
+ ROSS
141
+
142
+ God save the king!
143
+
144
+ DUNCAN
145
+
146
+ Whence camest thou, worthy thane?
147
+
148
+ ROSS
149
+
150
+ From Fife, great king;
151
+ Where the Norweyan banners flout the sky
152
+ And fan our people cold. Norway himself,
153
+ With terrible numbers,
154
+ Assisted by that most disloyal traitor
155
+ The thane of Cawdor, began a dismal conflict;
156
+ Till that Bellona's bridegroom, lapp'd in proof,
157
+ Confronted him with self-comparisons,
158
+ Point against point rebellious, arm 'gainst arm.
159
+ Curbing his lavish spirit: and, to conclude,
160
+ The victory fell on us.
161
+
162
+ DUNCAN
163
+
164
+ Great happiness!
165
+
166
+ ROSS
167
+
168
+ That now
169
+ Sweno, the Norways' king, craves composition:
170
+ Nor would we deign him burial of his men
171
+ Till he disbursed at Saint Colme's inch
172
+ Ten thousand dollars to our general use.
173
+
174
+ DUNCAN
175
+
176
+ No more that thane of Cawdor shall deceive
177
+ Our bosom interest: go pronounce his present death,
178
+ And with his former title greet Macbeth.
179
+
180
+ ROSS
181
+
182
+ I'll see it done.
183
+
184
+ DUNCAN
185
+
186
+ What he hath lost noble Macbeth hath won.
187
+
188
+ Exeunt
189
+
@@ -0,0 +1,534 @@
1
+ The Tragedy of Macbeth
2
+ Shakespeare homepage | Macbeth | Entire play
3
+ SCENE I. A desert place.
4
+
5
+ Thunder and lightning. Enter three Witches
6
+
7
+ First Witch
8
+
9
+ When shall we three meet again
10
+ In thunder, lightning, or in rain?
11
+
12
+ Second Witch
13
+
14
+ When the hurlyburly's done,
15
+ When the battle's lost and won.
16
+
17
+ Third Witch
18
+
19
+ That will be ere the set of sun.
20
+
21
+ First Witch
22
+
23
+ Where the place?
24
+
25
+ Second Witch
26
+
27
+ Upon the heath.
28
+
29
+ Third Witch
30
+
31
+ There to meet with Macbeth.
32
+
33
+ First Witch
34
+
35
+ I come, Graymalkin!
36
+
37
+ Second Witch
38
+
39
+ Paddock calls.
40
+
41
+ Third Witch
42
+
43
+ Anon.
44
+
45
+ ALL
46
+
47
+ Fair is foul, and foul is fair:
48
+ Hover through the fog and filthy air.
49
+
50
+ Exeunt
51
+
52
+ SCENE II. A camp near Forres.
53
+
54
+ Alarum within. Enter DUNCAN, MALCOLM, DONALBAIN, LENNOX, with Attendants, meeting a bleeding Sergeant
55
+
56
+ DUNCAN
57
+
58
+ What bloody man is that? He can report,
59
+ As seemeth by his plight, of the revolt
60
+ The newest state.
61
+
62
+ MALCOLM
63
+
64
+ This is the sergeant
65
+ Who like a good and hardy soldier fought
66
+ 'Gainst my captivity. Hail, brave friend!
67
+ Say to the king the knowledge of the broil
68
+ As thou didst leave it.
69
+
70
+ Sergeant
71
+
72
+ Doubtful it stood;
73
+ As two spent swimmers, that do cling together
74
+ And choke their art. The merciless Macdonwald--
75
+ Worthy to be a rebel, for to that
76
+ The multiplying villanies of nature
77
+ Do swarm upon him--from the western isles
78
+ Of kerns and gallowglasses is supplied;
79
+ And fortune, on his damned quarrel smiling,
80
+ Show'd like a rebel's whore: but all's too weak:
81
+ For brave Macbeth--well he deserves that name--
82
+ Disdaining fortune, with his brandish'd steel,
83
+ Which smoked with bloody execution,
84
+ Like valour's minion carved out his passage
85
+ Till he faced the slave;
86
+ Which ne'er shook hands, nor bade farewell to him,
87
+ Till he unseam'd him from the nave to the chaps,
88
+ And fix'd his head upon our battlements.
89
+
90
+ DUNCAN
91
+
92
+ O valiant cousin! worthy gentleman!
93
+
94
+ Sergeant
95
+
96
+ As whence the sun 'gins his reflection
97
+ Shipwrecking storms and direful thunders break,
98
+ So from that spring whence comfort seem'd to come
99
+ Discomfort swells. Mark, king of Scotland, mark:
100
+ No sooner justice had with valour arm'd
101
+ Compell'd these skipping kerns to trust their heels,
102
+ But the Norweyan lord surveying vantage,
103
+ With furbish'd arms and new supplies of men
104
+ Began a fresh assault.
105
+
106
+ DUNCAN
107
+
108
+ Dismay'd not this
109
+ Our captains, Macbeth and Banquo?
110
+
111
+ Sergeant
112
+
113
+ Yes;
114
+ As sparrows eagles, or the hare the lion.
115
+ If I say sooth, I must report they were
116
+ As cannons overcharged with double cracks, so they
117
+ Doubly redoubled strokes upon the foe:
118
+ Except they meant to bathe in reeking wounds,
119
+ Or memorise another Golgotha,
120
+ I cannot tell.
121
+ But I am faint, my gashes cry for help.
122
+
123
+ DUNCAN
124
+
125
+ So well thy words become thee as thy wounds;
126
+ They smack of honour both. Go get him surgeons.
127
+
128
+ Exit Sergeant, attended
129
+ Who comes here?
130
+
131
+ Enter ROSS
132
+
133
+ MALCOLM
134
+
135
+ The worthy thane of Ross.
136
+
137
+ LENNOX
138
+
139
+ What a haste looks through his eyes! So should he look
140
+ That seems to speak things strange.
141
+
142
+ ROSS
143
+
144
+ God save the king!
145
+
146
+ DUNCAN
147
+
148
+ Whence camest thou, worthy thane?
149
+
150
+ ROSS
151
+
152
+ From Fife, great king;
153
+ Where the Norweyan banners flout the sky
154
+ And fan our people cold. Norway himself,
155
+ With terrible numbers,
156
+ Assisted by that most disloyal traitor
157
+ The thane of Cawdor, began a dismal conflict;
158
+ Till that Bellona's bridegroom, lapp'd in proof,
159
+ Confronted him with self-comparisons,
160
+ Point against point rebellious, arm 'gainst arm.
161
+ Curbing his lavish spirit: and, to conclude,
162
+ The victory fell on us.
163
+
164
+ DUNCAN
165
+
166
+ Great happiness!
167
+
168
+ ROSS
169
+
170
+ That now
171
+ Sweno, the Norways' king, craves composition:
172
+ Nor would we deign him burial of his men
173
+ Till he disbursed at Saint Colme's inch
174
+ Ten thousand dollars to our general use.
175
+
176
+ DUNCAN
177
+
178
+ No more that thane of Cawdor shall deceive
179
+ Our bosom interest: go pronounce his present death,
180
+ And with his former title greet Macbeth.
181
+
182
+ ROSS
183
+
184
+ I'll see it done.
185
+
186
+ DUNCAN
187
+
188
+ What he hath lost noble Macbeth hath won.
189
+
190
+ Exeunt
191
+
192
+ SCENE III. A heath near Forres.
193
+
194
+ Thunder. Enter the three Witches
195
+
196
+ First Witch
197
+
198
+ Where hast thou been, sister?
199
+
200
+ Second Witch
201
+
202
+ Killing swine.
203
+
204
+ Third Witch
205
+
206
+ Sister, where thou?
207
+
208
+ First Witch
209
+
210
+ A sailor's wife had chestnuts in her lap,
211
+ And munch'd, and munch'd, and munch'd:--
212
+ 'Give me,' quoth I:
213
+ 'Aroint thee, witch!' the rump-fed ronyon cries.
214
+ Her husband's to Aleppo gone, master o' the Tiger:
215
+ But in a sieve I'll thither sail,
216
+ And, like a rat without a tail,
217
+ I'll do, I'll do, and I'll do.
218
+
219
+ Second Witch
220
+
221
+ I'll give thee a wind.
222
+
223
+ First Witch
224
+
225
+ Thou'rt kind.
226
+
227
+ Third Witch
228
+
229
+ And I another.
230
+
231
+ First Witch
232
+
233
+ I myself have all the other,
234
+ And the very ports they blow,
235
+ All the quarters that they know
236
+ I' the shipman's card.
237
+ I will drain him dry as hay:
238
+ Sleep shall neither night nor day
239
+ Hang upon his pent-house lid;
240
+ He shall live a man forbid:
241
+ Weary se'nnights nine times nine
242
+ Shall he dwindle, peak and pine:
243
+ Though his bark cannot be lost,
244
+ Yet it shall be tempest-tost.
245
+ Look what I have.
246
+
247
+ Second Witch
248
+
249
+ Show me, show me.
250
+
251
+ First Witch
252
+
253
+ Here I have a pilot's thumb,
254
+ Wreck'd as homeward he did come.
255
+
256
+ Drum within
257
+
258
+ Third Witch
259
+
260
+ A drum, a drum!
261
+ Macbeth doth come.
262
+
263
+ ALL
264
+
265
+ The weird sisters, hand in hand,
266
+ Posters of the sea and land,
267
+ Thus do go about, about:
268
+ Thrice to thine and thrice to mine
269
+ And thrice again, to make up nine.
270
+ Peace! the charm's wound up.
271
+
272
+ Enter MACBETH and BANQUO
273
+
274
+ MACBETH
275
+
276
+ So foul and fair a day I have not seen.
277
+
278
+ BANQUO
279
+
280
+ How far is't call'd to Forres? What are these
281
+ So wither'd and so wild in their attire,
282
+ That look not like the inhabitants o' the earth,
283
+ And yet are on't? Live you? or are you aught
284
+ That man may question? You seem to understand me,
285
+ By each at once her chappy finger laying
286
+ Upon her skinny lips: you should be women,
287
+ And yet your beards forbid me to interpret
288
+ That you are so.
289
+
290
+ MACBETH
291
+
292
+ Speak, if you can: what are you?
293
+
294
+ First Witch
295
+
296
+ All hail, Macbeth! hail to thee, thane of Glamis!
297
+
298
+ Second Witch
299
+
300
+ All hail, Macbeth, hail to thee, thane of Cawdor!
301
+
302
+ Third Witch
303
+
304
+ All hail, Macbeth, thou shalt be king hereafter!
305
+
306
+ BANQUO
307
+
308
+ Good sir, why do you start; and seem to fear
309
+ Things that do sound so fair? I' the name of truth,
310
+ Are ye fantastical, or that indeed
311
+ Which outwardly ye show? My noble partner
312
+ You greet with present grace and great prediction
313
+ Of noble having and of royal hope,
314
+ That he seems rapt withal: to me you speak not.
315
+ If you can look into the seeds of time,
316
+ And say which grain will grow and which will not,
317
+ Speak then to me, who neither beg nor fear
318
+ Your favours nor your hate.
319
+
320
+ First Witch
321
+
322
+ Hail!
323
+
324
+ Second Witch
325
+
326
+ Hail!
327
+
328
+ Third Witch
329
+
330
+ Hail!
331
+
332
+ First Witch
333
+
334
+ Lesser than Macbeth, and greater.
335
+
336
+ Second Witch
337
+
338
+ Not so happy, yet much happier.
339
+
340
+ Third Witch
341
+
342
+ Thou shalt get kings, though thou be none:
343
+ So all hail, Macbeth and Banquo!
344
+
345
+ First Witch
346
+
347
+ Banquo and Macbeth, all hail!
348
+
349
+ MACBETH
350
+
351
+ Stay, you imperfect speakers, tell me more:
352
+ By Sinel's death I know I am thane of Glamis;
353
+ But how of Cawdor? the thane of Cawdor lives,
354
+ A prosperous gentleman; and to be king
355
+ Stands not within the prospect of belief,
356
+ No more than to be Cawdor. Say from whence
357
+ You owe this strange intelligence? or why
358
+ Upon this blasted heath you stop our way
359
+ With such prophetic greeting? Speak, I charge you.
360
+
361
+ Witches vanish
362
+
363
+ BANQUO
364
+
365
+ The earth hath bubbles, as the water has,
366
+ And these are of them. Whither are they vanish'd?
367
+
368
+ MACBETH
369
+
370
+ Into the air; and what seem'd corporal melted
371
+ As breath into the wind. Would they had stay'd!
372
+
373
+ BANQUO
374
+
375
+ Were such things here as we do speak about?
376
+ Or have we eaten on the insane root
377
+ That takes the reason prisoner?
378
+
379
+ MACBETH
380
+
381
+ Your children shall be kings.
382
+
383
+ BANQUO
384
+
385
+ You shall be king.
386
+
387
+ MACBETH
388
+
389
+ And thane of Cawdor too: went it not so?
390
+
391
+ BANQUO
392
+
393
+ To the selfsame tune and words. Who's here?
394
+
395
+ Enter ROSS and ANGUS
396
+
397
+ ROSS
398
+
399
+ The king hath happily received, Macbeth,
400
+ The news of thy success; and when he reads
401
+ Thy personal venture in the rebels' fight,
402
+ His wonders and his praises do contend
403
+ Which should be thine or his: silenced with that,
404
+ In viewing o'er the rest o' the selfsame day,
405
+ He finds thee in the stout Norweyan ranks,
406
+ Nothing afeard of what thyself didst make,
407
+ Strange images of death. As thick as hail
408
+ Came post with post; and every one did bear
409
+ Thy praises in his kingdom's great defence,
410
+ And pour'd them down before him.
411
+
412
+ ANGUS
413
+
414
+ We are sent
415
+ To give thee from our royal master thanks;
416
+ Only to herald thee into his sight,
417
+ Not pay thee.
418
+
419
+ ROSS
420
+
421
+ And, for an earnest of a greater honour,
422
+ He bade me, from him, call thee thane of Cawdor:
423
+ In which addition, hail, most worthy thane!
424
+ For it is thine.
425
+
426
+ BANQUO
427
+
428
+ What, can the devil speak true?
429
+
430
+ MACBETH
431
+
432
+ The thane of Cawdor lives: why do you dress me
433
+ In borrow'd robes?
434
+
435
+ ANGUS
436
+
437
+ Who was the thane lives yet;
438
+ But under heavy judgment bears that life
439
+ Which he deserves to lose. Whether he was combined
440
+ With those of Norway, or did line the rebel
441
+ With hidden help and vantage, or that with both
442
+ He labour'd in his country's wreck, I know not;
443
+ But treasons capital, confess'd and proved,
444
+ Have overthrown him.
445
+
446
+ MACBETH
447
+
448
+ [Aside] Glamis, and thane of Cawdor!
449
+ The greatest is behind.
450
+
451
+ To ROSS and ANGUS
452
+ Thanks for your pains.
453
+
454
+ To BANQUO
455
+ Do you not hope your children shall be kings,
456
+ When those that gave the thane of Cawdor to me
457
+ Promised no less to them?
458
+
459
+ BANQUO
460
+
461
+ That trusted home
462
+ Might yet enkindle you unto the crown,
463
+ Besides the thane of Cawdor. But 'tis strange:
464
+ And oftentimes, to win us to our harm,
465
+ The instruments of darkness tell us truths,
466
+ Win us with honest trifles, to betray's
467
+ In deepest consequence.
468
+ Cousins, a word, I pray you.
469
+
470
+ MACBETH
471
+
472
+ [Aside] Two truths are told,
473
+ As happy prologues to the swelling act
474
+ Of the imperial theme.--I thank you, gentlemen.
475
+
476
+ Aside
477
+ Cannot be ill, cannot be good: if ill,
478
+ Why hath it given me earnest of success,
479
+ Commencing in a truth? I am thane of Cawdor:
480
+ If good, why do I yield to that suggestion
481
+ Whose horrid image doth unfix my hair
482
+ And make my seated heart knock at my ribs,
483
+ Against the use of nature? Present fears
484
+ Are less than horrible imaginings:
485
+ My thought, whose murder yet is but fantastical,
486
+ Shakes so my single state of man that function
487
+ Is smother'd in surmise, and nothing is
488
+ But what is not.
489
+
490
+ BANQUO
491
+
492
+ Look, how our partner's rapt.
493
+
494
+ MACBETH
495
+
496
+ [Aside] If chance will have me king, why, chance may crown me,
497
+ Without my stir.
498
+
499
+ BANQUO
500
+
501
+ New horrors come upon him,
502
+ Like our strange garments, cleave not to their mould
503
+ But with the aid of use.
504
+
505
+ MACBETH
506
+
507
+ [Aside] Come what come may,
508
+ Time and the hour runs through the roughest day.
509
+
510
+ BANQUO
511
+
512
+ Worthy Macbeth, we stay upon your leisure.
513
+
514
+ MACBETH
515
+
516
+ Give me your favour: my dull brain was wrought
517
+ With things forgotten. Kind gentlemen, your pains
518
+ Are register'd where every day I turn
519
+ The leaf to read them. Let us toward the king.
520
+ Think upon what hath chanced, and, at more time,
521
+ The interim having weigh'd it, let us speak
522
+ Our free hearts each to other.
523
+
524
+ BANQUO
525
+
526
+ Very gladly.
527
+
528
+ MACBETH
529
+
530
+ Till then, enough. Come, friends.
531
+
532
+ Exeunt
533
+
534
+
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format nested
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'spec'
4
+ require 'spec/autorun'
5
+ require File.expand_path(File.dirname(__FILE__) + '/ssdeep_behaviors')
6
+
7
+
8
+ Spec::Runner.configure do |config|
9
+
10
+ end
11
+
12
+ def sample_file(fname)
13
+ File.expand_path(File.join(File.dirname(__FILE__), "samples", fname))
14
+ end
15
+
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for 'the Ssdeep interface' do
4
+ it "should generate hashes for strings" do
5
+ @klass.from_string(File.read(@f1)).should == @f1_hash
6
+ @klass.from_string(File.read(@f2)).should == @f2_hash
7
+ end
8
+
9
+ it "should generate hashes from filenames" do
10
+ @klass.from_file(@f1).should == @f1_hash
11
+ @klass.from_file(@f2).should == @f2_hash
12
+ end
13
+
14
+ it "should generate hashes for file descriptor numbers" do
15
+ @klass.from_fileno(File.new(@f1, 'r').fileno).should == @f1_hash
16
+ @klass.from_fileno(File.new(@f2, 'r').fileno).should == @f2_hash
17
+ end
18
+
19
+ it "should compare two hashes from the same string correctly" do
20
+ @klass.compare(
21
+ @klass.from_string(File.read @f1),
22
+ @klass.from_string(File.read @f1)
23
+ ).should == 100
24
+ end
25
+
26
+
27
+ it "should compare two hashes from the different strings correctly" do
28
+ @klass.compare(
29
+ @klass.from_string(File.read @f1),
30
+ @klass.from_string(File.read @f2)
31
+ ).should > 50
32
+ end
33
+
34
+ it "should compare two hashes from the same filename correctly" do
35
+ @klass.compare(
36
+ @klass.from_file(@f1),
37
+ @klass.from_file(@f1)
38
+ ).should == 100
39
+ end
40
+
41
+ it "should compare two hashes from different filenames correctly" do
42
+ @klass.compare(
43
+ @klass.from_file(@f1),
44
+ @klass.from_file(@f2)
45
+ ).should > 50
46
+ end
47
+
48
+ # this test seems to really confuse poor java... go figure...
49
+ # homer says: stupid java!
50
+ unless RUBY_PLATFORM =~ /java/
51
+ it "should compare two hashes from file descriptors with the same file" do
52
+ @klass.compare(
53
+ @klass.from_fileno(File.new(@f1, 'r').fileno),
54
+ @klass.from_fileno(File.new(@f1, 'r').fileno)
55
+ ).should == 100
56
+ end
57
+ end
58
+
59
+ it "should compare two hashes from different file descriptors" do
60
+ @klass.compare(
61
+ @klass.from_fileno(File.new(@f1, 'r').fileno),
62
+ @klass.from_fileno(File.new(@f2, 'r').fileno)
63
+ ).should > 50
64
+ end
65
+
66
+
67
+ it "should raise an exception when hashing invalid objects" do
68
+ lambda {@klass.from_fileno(nil)}.should raise_error
69
+ lambda {@klass.from_string(nil)}.should raise_error
70
+ lambda {@klass.from_file(nil)}.should raise_error
71
+ end
72
+
73
+ it "should raise an exception when hashing an invalid fileno" do
74
+ # ensure we're passing in an invalid fd, by opening and closing it ourself
75
+ fd = File.open(sample_file('sample1.txt')) {|f| f.fileno }
76
+
77
+ lambda {@klass.from_fileno(fd)}.should raise_error
78
+ end
79
+
80
+ it "should raise an exception when hashing an invalid file" do
81
+ lambda {@klass.from_fileno(sample_file('bogusfile'))}.should raise_error
82
+ end
83
+
84
+ end
@@ -0,0 +1,33 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'ssdeep'
3
+
4
+ describe Ssdeep do
5
+ before(:all) {
6
+ @klass = Ssdeep
7
+
8
+ @f1 = sample_file("sample1.txt")
9
+ @f2 = sample_file("sample2.txt")
10
+
11
+ @f1_hash = '96:tQWAFF4IMtG6z4FEmYqGPUyukJM4kbqkTKL+LGw6b8f/EZMhJvybtSryfubB:tO4a68FZYqyG4w2+Bbzhpybg6u9'
12
+ @f2_hash = '192:sO4a68FZYqyG4w2+Bbzhpybg6uTI6l7yrnUxioPmSKx/A0IV2vRqtJUF2CnHqVC2:sOf6aYqyG4w3ug6uTI6lQUxioOLx/AZt'
13
+ }
14
+
15
+ # this seems to really mess up java... go figure... homer says: stupid java!
16
+ unless RUBY_PLATFORM =~ /java/
17
+ it "should compare two hashes from file descriptors with the same file" do
18
+ @klass.compare(
19
+ @klass.from_fileno(File.new(@f1, 'r').fileno),
20
+ @klass.from_fileno(File.new(@f1, 'r').fileno)
21
+ ).should == 100
22
+ end
23
+
24
+ it "should compare two hashes from different file descriptors" do
25
+ @klass.compare(
26
+ @klass.from_fileno(File.new(@f1, 'r').fileno),
27
+ @klass.from_fileno(File.new(@f2, 'r').fileno)
28
+ ).should > 50
29
+ end
30
+ end
31
+
32
+ it_should_behave_like 'the Ssdeep interface'
33
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: russdeep
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Eric Monti
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-02-20 00:00:00 -06:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 2
30
+ - 9
31
+ version: 1.2.9
32
+ type: :development
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: ffi
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :development
45
+ version_requirements: *id002
46
+ description: Ruby bindings for libfuzzy, a fuzzy hashing implementation included with the ssdeep utility
47
+ email: esmonti@gmail.com
48
+ executables: []
49
+
50
+ extensions:
51
+ - ext/ssdeep_native/extconf.rb
52
+ extra_rdoc_files:
53
+ - LICENSE
54
+ - README.rdoc
55
+ files:
56
+ - .document
57
+ - LICENSE
58
+ - README.rdoc
59
+ - Rakefile
60
+ - VERSION
61
+ - ext/ssdeep_native/extconf.rb
62
+ - ext/ssdeep_native/ssdeep_native.c
63
+ - lib/ffi/ssdeep.rb
64
+ - lib/russdeep.rb
65
+ - lib/ssdeep.rb
66
+ - lib/ssdeep_ffi.rb
67
+ - spec/ffi_ssdeep_spec.rb
68
+ - spec/samples/sample1.txt
69
+ - spec/samples/sample2.txt
70
+ - spec/spec.opts
71
+ - spec/spec_helper.rb
72
+ - spec/ssdeep_behaviors.rb
73
+ - spec/ssdeep_spec.rb
74
+ has_rdoc: true
75
+ homepage: http://github.com/emonti/russdeep
76
+ licenses: []
77
+
78
+ post_install_message:
79
+ rdoc_options: []
80
+
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ segments:
95
+ - 0
96
+ version: "0"
97
+ requirements: []
98
+
99
+ rubyforge_project:
100
+ rubygems_version: 1.3.6
101
+ signing_key:
102
+ specification_version: 3
103
+ summary: Ruby bindings for libfuzzy (from ssdeep)
104
+ test_files:
105
+ - spec/ffi_ssdeep_spec.rb
106
+ - spec/spec_helper.rb
107
+ - spec/ssdeep_behaviors.rb
108
+ - spec/ssdeep_spec.rb