russdeep 1.0.0 → 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/.document +1 -0
- data/{spec/spec.opts → .rspec} +0 -0
- data/History.txt +9 -0
- data/Rakefile +13 -5
- data/VERSION +1 -1
- data/ext/ssdeep_native/ssdeep_native.c +44 -0
- data/lib/ffi/ssdeep.rb +32 -0
- data/lib/russdeep.rb +45 -0
- data/lib/ssdeep.rb +51 -0
- data/spec/fuzzy_comparable_spec.rb +21 -0
- data/spec/spec_helper.rb +1 -2
- metadata +13 -5
data/.document
CHANGED
data/{spec/spec.opts → .rspec}
RENAMED
File without changes
|
data/History.txt
ADDED
data/Rakefile
CHANGED
@@ -16,6 +16,7 @@ begin
|
|
16
16
|
|
17
17
|
if RUBY_PLATFORM !~ /java/
|
18
18
|
gem.extensions = FileList['ext/**/extconf.rb']
|
19
|
+
gem.extra_rdoc_files += FileList['ext/**/*.c']
|
19
20
|
end
|
20
21
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
21
22
|
end
|
@@ -24,18 +25,20 @@ rescue LoadError
|
|
24
25
|
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
25
26
|
end
|
26
27
|
|
27
|
-
require '
|
28
|
-
|
29
|
-
spec.
|
30
|
-
spec.spec_files = FileList['spec/ssdeep_spec.rb', 'spec/**/*_spec.rb'].uniq
|
28
|
+
require 'rspec/core/rake_task'
|
29
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
30
|
+
spec.pattern = FileList['spec/ssdeep_spec.rb', 'spec/**/*_spec.rb'].uniq
|
31
31
|
end
|
32
32
|
|
33
33
|
if RUBY_PLATFORM !~ /java/
|
34
34
|
Rake::ExtensionTask.new("ssdeep_native")
|
35
35
|
|
36
|
+
CLEAN.include("doc")
|
37
|
+
CLEAN.include("rdoc")
|
38
|
+
CLEAN.include("coverage")
|
39
|
+
CLEAN.include("tmp")
|
36
40
|
CLEAN.include("lib/*.bundle")
|
37
41
|
CLEAN.include("lib/*.so")
|
38
|
-
CLEAN.include("tmp")
|
39
42
|
|
40
43
|
task :spec => :compile
|
41
44
|
end
|
@@ -53,4 +56,9 @@ Rake::RDocTask.new do |rdoc|
|
|
53
56
|
rdoc.title = "russdeep #{version}"
|
54
57
|
rdoc.rdoc_files.include('README*')
|
55
58
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
59
|
+
rdoc.rdoc_files.include('ext/**/*.c')
|
56
60
|
end
|
61
|
+
|
62
|
+
require 'yard'
|
63
|
+
YARD::Rake::YardocTask.new
|
64
|
+
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.1.0
|
@@ -5,6 +5,17 @@
|
|
5
5
|
static VALUE module_Ssdeep = Qnil;
|
6
6
|
static VALUE error_HashError = Qnil;
|
7
7
|
|
8
|
+
/* call-seq: from_string(buf)
|
9
|
+
*
|
10
|
+
* Create a fuzzy hash from a ruby string
|
11
|
+
*
|
12
|
+
* @param String buf The string to hash
|
13
|
+
*
|
14
|
+
* @return String The fuzzy hash of the string
|
15
|
+
*
|
16
|
+
* @raise HashError
|
17
|
+
* An exception is raised if the libfuzzy library encounters an error.
|
18
|
+
*/
|
8
19
|
VALUE ssdeep_from_string(VALUE klass, VALUE buf) {
|
9
20
|
char hash[FUZZY_MAX_RESULT];
|
10
21
|
int ret;
|
@@ -17,6 +28,17 @@ VALUE ssdeep_from_string(VALUE klass, VALUE buf) {
|
|
17
28
|
rb_raise(error_HashError, "An error occurred hashing a string: ret=%i", ret);
|
18
29
|
}
|
19
30
|
|
31
|
+
/* call-seq: from_file(filename)
|
32
|
+
*
|
33
|
+
* Create a fuzzy hash from a file
|
34
|
+
*
|
35
|
+
* @param String fielname The file to read and hash
|
36
|
+
*
|
37
|
+
* @return String The fuzzy hash of the file input
|
38
|
+
*
|
39
|
+
* @raise HashError
|
40
|
+
* An exception is raised if the libfuzzy library encounters an error.
|
41
|
+
*/
|
20
42
|
VALUE ssdeep_from_filename(VALUE klass, VALUE filename) {
|
21
43
|
char hash[FUZZY_MAX_RESULT];
|
22
44
|
int ret;
|
@@ -29,6 +51,17 @@ VALUE ssdeep_from_filename(VALUE klass, VALUE filename) {
|
|
29
51
|
rb_raise(error_HashError, "An error occurred the file: %s -- ret=%i", RSTRING_PTR(filename), ret);
|
30
52
|
}
|
31
53
|
|
54
|
+
/* call-seq: from_fileno(fileno)
|
55
|
+
*
|
56
|
+
* Create a fuzzy hash from a file descriptor fileno
|
57
|
+
*
|
58
|
+
* @param Integer fileno The file descriptor to read and hash
|
59
|
+
*
|
60
|
+
* @return String The fuzzy hash of the file descriptor input
|
61
|
+
*
|
62
|
+
* @raise HashError
|
63
|
+
* An exception is raised if the libfuzzy library encounters an error.
|
64
|
+
*/
|
32
65
|
VALUE ssdeep_from_fileno(VALUE klass, VALUE fileno) {
|
33
66
|
char hash[FUZZY_MAX_RESULT];
|
34
67
|
int ret, fd;
|
@@ -50,6 +83,17 @@ VALUE ssdeep_from_fileno(VALUE klass, VALUE fileno) {
|
|
50
83
|
rb_raise(error_HashError, "An error occurred the fileno: %i -- ret=%i", fd, ret);
|
51
84
|
}
|
52
85
|
|
86
|
+
/* call-seq: compare(sig1, sig2)
|
87
|
+
*
|
88
|
+
* Compare two hashes
|
89
|
+
*
|
90
|
+
* @param String sig1 A fuzzy hash which will be compared to sig2
|
91
|
+
*
|
92
|
+
* @param String sig2 A fuzzy hash which will be compared to sig1
|
93
|
+
*
|
94
|
+
* @return Integer
|
95
|
+
* A value between 0 and 100 indicating the percentage of similarity.
|
96
|
+
*/
|
53
97
|
VALUE ssdeep_compare(VALUE klass, VALUE sig1, VALUE sig2) {
|
54
98
|
int ret;
|
55
99
|
|
data/lib/ffi/ssdeep.rb
CHANGED
@@ -27,6 +27,14 @@ module Ssdeep
|
|
27
27
|
attach_function :fdopen, [:int, :string], :pointer
|
28
28
|
|
29
29
|
|
30
|
+
# Create a fuzzy hash from a ruby string
|
31
|
+
#
|
32
|
+
# @param String buf The string to hash
|
33
|
+
#
|
34
|
+
# @return String The fuzzy hash of the string
|
35
|
+
#
|
36
|
+
# @raise HashError
|
37
|
+
# An exception is raised if the libfuzzy library encounters an error.
|
30
38
|
def self.from_string(buf)
|
31
39
|
bufp = FFI::MemoryPointer.new(buf.size)
|
32
40
|
bufp.write_string(buf)
|
@@ -40,6 +48,14 @@ module Ssdeep
|
|
40
48
|
end
|
41
49
|
end
|
42
50
|
|
51
|
+
# Create a fuzzy hash from a file descriptor fileno
|
52
|
+
#
|
53
|
+
# @param Integer fileno The file descriptor to read and hash
|
54
|
+
#
|
55
|
+
# @return String The fuzzy hash of the file descriptor input
|
56
|
+
#
|
57
|
+
# @raise HashError
|
58
|
+
# An exception is raised if the libfuzzy library encounters an error.
|
43
59
|
def self.from_fileno(fileno)
|
44
60
|
if (not fileno.kind_of?(Integer)) or (file=fdopen(fileno, "r")).null?
|
45
61
|
raise(HashError, "Unable to open file descriptor: #{fileno}")
|
@@ -54,6 +70,14 @@ module Ssdeep
|
|
54
70
|
end
|
55
71
|
end
|
56
72
|
|
73
|
+
# Create a fuzzy hash from a file
|
74
|
+
#
|
75
|
+
# @param String fielname The file to read and hash
|
76
|
+
#
|
77
|
+
# @return String The fuzzy hash of the file input
|
78
|
+
#
|
79
|
+
# @raise HashError
|
80
|
+
# An exception is raised if the libfuzzy library encounters an error.
|
57
81
|
def self.from_file(filename)
|
58
82
|
File.stat(filename)
|
59
83
|
out = FFI::MemoryPointer.new(FUZZY_MAX_RESULT)
|
@@ -65,6 +89,14 @@ module Ssdeep
|
|
65
89
|
end
|
66
90
|
end
|
67
91
|
|
92
|
+
# Compare two hashes
|
93
|
+
#
|
94
|
+
# @param String sig1 A fuzzy hash which will be compared to sig2
|
95
|
+
#
|
96
|
+
# @param String sig2 A fuzzy hash which will be compared to sig1
|
97
|
+
#
|
98
|
+
# @return Integer
|
99
|
+
# A value between 0 and 100 indicating the percentage of similarity.
|
68
100
|
def self.compare(sig1, sig2)
|
69
101
|
psig1 = FFI::MemoryPointer.from_string(sig1)
|
70
102
|
psig2 = FFI::MemoryPointer.from_string(sig2)
|
data/lib/russdeep.rb
CHANGED
@@ -1,3 +1,48 @@
|
|
1
1
|
require 'ssdeep'
|
2
2
|
|
3
|
+
|
4
|
+
module Ssdeep
|
5
|
+
# The FuzzyComparable module adds mixins for doing fuzzy hash comparisons.
|
6
|
+
# The object extending must simply implement the 'ssdeep' method, which
|
7
|
+
# should return a string containing a fuzzy CTPH hash.
|
8
|
+
module FuzzyComparable
|
9
|
+
# Returns a CTPH comparison score between this object and another's
|
10
|
+
# fuzzy hash.
|
11
|
+
#
|
12
|
+
# @param String,Object other
|
13
|
+
# The hash string or other object to compare to. If other is not
|
14
|
+
# a string, it just needs to implement the 'ssdeep' method.
|
15
|
+
#
|
16
|
+
def fuzzy_score(other)
|
17
|
+
other_hash=
|
18
|
+
if other.is_a? String
|
19
|
+
other
|
20
|
+
elsif other.respond_to? :ssdeep
|
21
|
+
other.ssdeep
|
22
|
+
else
|
23
|
+
raise(TypeError, "can't handle type for other: #{other.class}")
|
24
|
+
end
|
25
|
+
|
26
|
+
Ssdeep.compare(self.ssdeep, other_hash)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns true/false whether the sample matches a CTPH (fuzzy hash)
|
30
|
+
# with a score above a specified threshold
|
31
|
+
#
|
32
|
+
# @param String,Object other
|
33
|
+
# The hash string or other object to compare to. If other is not
|
34
|
+
# a string, it just needs to implement the 'ssdeep' method.
|
35
|
+
#
|
36
|
+
# @param Integer threshold
|
37
|
+
# The theshold above-which a match is considered true. If a threshold
|
38
|
+
# is supplied above 100, it is treated as 100.
|
39
|
+
#
|
40
|
+
# @return true,false
|
41
|
+
# Whether a match occurred.
|
42
|
+
def fuzzy_match(other, threshold=25)
|
43
|
+
return (fuzzy_score(other) >= [threshold, 100].min)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
3
48
|
RuSsdeep = Ssdeep
|
data/lib/ssdeep.rb
CHANGED
@@ -5,3 +5,54 @@ else
|
|
5
5
|
require 'ssdeep_native'
|
6
6
|
end
|
7
7
|
|
8
|
+
module Ssdeep
|
9
|
+
# The FuzzyComparable module adds mixins for doing fuzzy hash comparisons.
|
10
|
+
# To mix in the module your object must simply implement the 'ssdeep'
|
11
|
+
# method, which should return a string containing a fuzzy CTPH hash.
|
12
|
+
module FuzzyComparable
|
13
|
+
# Returns a CTPH comparison score between this object and another's
|
14
|
+
# fuzzy hash.
|
15
|
+
#
|
16
|
+
# @param String,Object other
|
17
|
+
# The hash string or other object to compare to. If other is not
|
18
|
+
# a string, it just needs to implement the 'ssdeep' method.
|
19
|
+
#
|
20
|
+
def fuzzy_score(other)
|
21
|
+
other_hash=
|
22
|
+
if other.is_a? String
|
23
|
+
other
|
24
|
+
elsif other.respond_to? :ssdeep
|
25
|
+
other.ssdeep
|
26
|
+
else
|
27
|
+
raise(TypeError, "can't handle type for other: #{other.class}")
|
28
|
+
end
|
29
|
+
|
30
|
+
Ssdeep.compare(self.ssdeep, other_hash)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns true/false whether the sample matches a CTPH (fuzzy hash)
|
34
|
+
# with a score above a specified threshold
|
35
|
+
#
|
36
|
+
# @param String,Object other
|
37
|
+
# The hash string or other object to compare to. If other is not
|
38
|
+
# a string, it just needs to implement the 'ssdeep' method.
|
39
|
+
#
|
40
|
+
# @param Integer threshold
|
41
|
+
# The theshold above-which a match is considered true. If a threshold
|
42
|
+
# is supplied above 100, it is treated as 100.
|
43
|
+
#
|
44
|
+
# @return true,false
|
45
|
+
# Whether a match occurred.
|
46
|
+
def fuzzy_match(other, threshold=25)
|
47
|
+
return (fuzzy_score(other) >= [threshold, 100].min)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class << self
|
52
|
+
alias :hash_string :from_string
|
53
|
+
alias :hash_file :from_file
|
54
|
+
alias :hash_fileno :from_fileno
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'ssdeep'
|
3
|
+
|
4
|
+
class TestFuzzyComparable
|
5
|
+
include Ssdeep::FuzzyComparable
|
6
|
+
|
7
|
+
def ssdeep
|
8
|
+
'96:tQWAFF4IMtG6z4FEmYqGPUyukJM4kbqkTKL+LGw6b8f/EZMhJvybtSryfubB:tO4a68FZYqyG4w2+Bbzhpybg6u9'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe Ssdeep::FuzzyComparable do
|
13
|
+
before :all do
|
14
|
+
@obj = TestFuzzyComparable.new
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should compare itself to another fuzzy hash string" do
|
18
|
+
@obj.fuzzy_score(Ssdeep.from_file sample_file("sample1.txt")).should == 100
|
19
|
+
@obj.fuzzy_match(Ssdeep.from_file sample_file("sample1.txt")).should be_true
|
20
|
+
end
|
21
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 1
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: 1.0.0
|
9
|
+
version: 1.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Eric Monti
|
@@ -14,13 +14,14 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-
|
17
|
+
date: 2011-03-22 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rspec
|
22
22
|
prerelease: false
|
23
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
24
25
|
requirements:
|
25
26
|
- - ">="
|
26
27
|
- !ruby/object:Gem::Version
|
@@ -35,6 +36,7 @@ dependencies:
|
|
35
36
|
name: ffi
|
36
37
|
prerelease: false
|
37
38
|
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
38
40
|
requirements:
|
39
41
|
- - ">="
|
40
42
|
- !ruby/object:Gem::Version
|
@@ -52,8 +54,11 @@ extensions:
|
|
52
54
|
extra_rdoc_files:
|
53
55
|
- LICENSE
|
54
56
|
- README.rdoc
|
57
|
+
- ext/ssdeep_native/ssdeep_native.c
|
55
58
|
files:
|
56
59
|
- .document
|
60
|
+
- .rspec
|
61
|
+
- History.txt
|
57
62
|
- LICENSE
|
58
63
|
- README.rdoc
|
59
64
|
- Rakefile
|
@@ -65,9 +70,9 @@ files:
|
|
65
70
|
- lib/ssdeep.rb
|
66
71
|
- lib/ssdeep_ffi.rb
|
67
72
|
- spec/ffi_ssdeep_spec.rb
|
73
|
+
- spec/fuzzy_comparable_spec.rb
|
68
74
|
- spec/samples/sample1.txt
|
69
75
|
- spec/samples/sample2.txt
|
70
|
-
- spec/spec.opts
|
71
76
|
- spec/spec_helper.rb
|
72
77
|
- spec/ssdeep_behaviors.rb
|
73
78
|
- spec/ssdeep_spec.rb
|
@@ -81,6 +86,7 @@ rdoc_options: []
|
|
81
86
|
require_paths:
|
82
87
|
- lib
|
83
88
|
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
84
90
|
requirements:
|
85
91
|
- - ">="
|
86
92
|
- !ruby/object:Gem::Version
|
@@ -88,6 +94,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
88
94
|
- 0
|
89
95
|
version: "0"
|
90
96
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
91
98
|
requirements:
|
92
99
|
- - ">="
|
93
100
|
- !ruby/object:Gem::Version
|
@@ -97,12 +104,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
104
|
requirements: []
|
98
105
|
|
99
106
|
rubyforge_project:
|
100
|
-
rubygems_version: 1.3.
|
107
|
+
rubygems_version: 1.3.7
|
101
108
|
signing_key:
|
102
109
|
specification_version: 3
|
103
110
|
summary: Ruby bindings for libfuzzy (from ssdeep)
|
104
111
|
test_files:
|
105
112
|
- spec/ffi_ssdeep_spec.rb
|
113
|
+
- spec/fuzzy_comparable_spec.rb
|
106
114
|
- spec/spec_helper.rb
|
107
115
|
- spec/ssdeep_behaviors.rb
|
108
116
|
- spec/ssdeep_spec.rb
|