crcs 0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 715a18e23f830edb25d180f89c2e3dd42826a799
4
+ data.tar.gz: 117c739f0113b25e7fc016e0989cef568b4090ca
5
+ SHA512:
6
+ metadata.gz: 214a0ba671a70b6d275cf0dbe2516c254ddb28a053205980de7f98ad75abb3d0d7d800da59a68fcea3eb94eef893f385fdf91c14ecc7674521f52a1424b68d82
7
+ data.tar.gz: c20a504b9d6bc31ccf631ba03ea697af6a5068d51276e70932569a4fbdca169eb221df034a67bd5910082578255ef8ecb6506ead03b9058668ad5259e9295084
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,70 @@
1
+ # Crcs
2
+
3
+ This gem provides C extension for calculating CRC32 digests. It's based on
4
+ table-driven slice-by-8 CRC32 algorithm.
5
+
6
+ ## Installation
7
+
8
+ Nothing special. Simply run
9
+
10
+ ```
11
+ gem install crcs
12
+ ```
13
+
14
+ or add folowing line to your Gemfile
15
+
16
+ ```ruby
17
+ gem 'crcs'
18
+ ```
19
+
20
+ ## Using
21
+
22
+ This gem integrates to Ruby Digest module. This way you can easily use
23
+ all methods that this module provides. Just use `Digest::CRC32` class after
24
+ requiring gem into your code. For example:
25
+
26
+ ```ruby
27
+ # Generate hexdigest for sample string
28
+ Digest::CRC32.hexdigest('Your data')
29
+ # or
30
+ crc32 = Digest::CRC32.new
31
+ crc32 << 'Data'
32
+ crc32 << 'More data'
33
+ crc32.hexdigest
34
+
35
+ # Generate file digest
36
+ Digest::CRC32.file('filename.txt').hexdigest
37
+ ```
38
+
39
+ ## Performance
40
+
41
+ Let's compare this gem with few others:
42
+ * [crc32](https://github.com/tdobrovolskij/crc32) which provides C extension with
43
+ the same algorithm but without all that fancy Digest module staff. It has only one method
44
+ `calculate`. So you should care about previous crc32 digests and data length by yourself
45
+ * Standard zlib ruby implementation
46
+ * [digest-crc](https://github.com/postmodern/digest-crc) which is pure Ruby
47
+ implementation of few CRC-algorithms
48
+
49
+ ### Benchmarking method
50
+
51
+ First of all we will create a string with random data provided by `SecureRandom.random_bytes`.
52
+ I choosed variable with 5 megabytes of random bytes
53
+ Next let's create digest for that string 1000 times by each of gems.
54
+
55
+ *All benchmarks performed on MacBook Pro 15 mid 2015 with 2,2 GHz Intel Core i7*
56
+
57
+ ### Results
58
+
59
+ ```
60
+ user system total real
61
+ crcs 12.660000 0.030000 12.690000 ( 12.709954)
62
+ tdobrovolskij/crc32 3.550000 0.010000 3.560000 ( 3.574127)
63
+ zlib 0.470000 0.000000 0.470000 ( 0.471863)
64
+ postmodern/digest-crc 947.670000 1.330000 949.000000 (950.414528)
65
+ ```
66
+ For some reasons my gem is terribly slower than crc32 and zlib libraries. I think
67
+ it's caused by overhead of creating digest objects and other things that happening inside
68
+ of that module. Maybe I should extract my code to separate class and try again?
69
+ Fortunately, as you can see, my gem isn't so bad comparing with pure ruby implementation.
70
+
@@ -0,0 +1,12 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rake/extensiontask'
4
+ Rake::ExtensionTask.new('crc32') do |ext|
5
+ ext.ext_dir = 'ext/digest/crc32'
6
+ ext.lib_dir = 'lib/digest'
7
+ end
8
+
9
+ require 'rspec/core/rake_task'
10
+ RSpec::Core::RakeTask.new(spec: :compile)
11
+
12
+ task default: :spec
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'digest/crc32/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'crcs'
8
+ spec.version = Digest::CRC32::VERSION
9
+ spec.authors = ['Nikolay Norkin']
10
+ spec.email = ['n.e.norkin@gmail.com']
11
+
12
+ spec.summary = 'CRC32 implementation for Ruby'
13
+ spec.description = 'This gem contains C extension for calculating CRC32'
14
+ spec.homepage = 'https://github.com/duderman/crcs'
15
+ spec.licenses = ['MIT']
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|benchmark)}) }
18
+ spec.extensions = ['ext/digest/crc32/extconf.rb']
19
+ spec.require_paths = ['lib']
20
+ spec.required_ruby_version = '~> 2.2'
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.11'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rake-compiler', '~> 0.9'
25
+ spec.add_development_dependency 'rspec', '~> 3.0'
26
+ end
@@ -0,0 +1,150 @@
1
+ #include "digest.h"
2
+ #include "crc32.h"
3
+
4
+ static const unsigned long crc_table[256] = {
5
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
6
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
7
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
8
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
9
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
10
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
11
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
12
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
13
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
14
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
15
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
16
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
17
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
18
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
19
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
20
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
21
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
22
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
23
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
24
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
25
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
26
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
27
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
28
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
29
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
30
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
31
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
32
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
33
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
34
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
35
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
36
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
37
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
38
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
39
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
40
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
41
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
42
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
43
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
44
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
45
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
46
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
47
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
48
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
49
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
50
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
51
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
52
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
53
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
54
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
55
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
56
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
57
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
58
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
59
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
60
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
61
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
62
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
63
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
64
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
65
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
66
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
67
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
68
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
69
+ };
70
+
71
+ int
72
+ CRC32_Init(CRC32_CTX *pms)
73
+ {
74
+ pms->count[0] = pms->count[1] = 0;
75
+ pms->state[0] = 0xFFFFFFFF;
76
+
77
+ return 1;
78
+ }
79
+
80
+ void
81
+ CRC32_Update(CRC32_CTX *pms, const uint8_t *data, size_t nbytes)
82
+ {
83
+ register uint32_t crc = pms->state[0];
84
+ register const uint8_t *p = data;
85
+ uint32_t nbits = (uint32_t)(nbytes << 3);
86
+ uint32_t tbl_idx;
87
+
88
+ if (nbytes <= 0)
89
+ return;
90
+
91
+ /* Update the message length. */
92
+ pms->count[1] += nbytes >> 29;
93
+ pms->count[0] += nbits;
94
+ if (pms->count[0] < nbits)
95
+ pms->count[1]++;
96
+
97
+ /* Update */
98
+ while (nbytes--) {
99
+ tbl_idx = (crc ^ *p) & 0xff;
100
+ crc = (crc_table[tbl_idx] ^ (crc >> 8)) & 0xffffffff;
101
+
102
+ p++;
103
+ }
104
+ crc &= 0xffffffff;
105
+
106
+ pms->state[0] = crc;
107
+ }
108
+
109
+ int
110
+ CRC32_Finish(CRC32_CTX *pms, uint8_t *digest)
111
+ {
112
+ register uint32_t crc = pms->state[0] ^ 0xFFFFFFFF;
113
+ register int i;
114
+
115
+ for (i = 3; i >= 0; i--)
116
+ {
117
+ digest[i] = (uint8_t)(crc & 0xFF);
118
+ crc = crc >> 8;
119
+ }
120
+
121
+ return 1;
122
+ }
123
+
124
+ static const rb_digest_metadata_t crc32 = {
125
+ RUBY_DIGEST_API_VERSION,
126
+ CRC32_DIGEST_LENGTH,
127
+ CRC32_BLOCK_LENGTH,
128
+ sizeof(CRC32_CTX),
129
+ (rb_digest_hash_init_func_t)CRC32_Init,
130
+ (rb_digest_hash_update_func_t)CRC32_Update,
131
+ (rb_digest_hash_finish_func_t)CRC32_Finish,
132
+ };
133
+
134
+ void
135
+ Init_crc32(void)
136
+ {
137
+ VALUE mDigest, cDigest_Base, cDigest_CRC32;
138
+
139
+ rb_require("digest.so");
140
+
141
+ mDigest = rb_path2class("Digest");
142
+ cDigest_Base = rb_path2class("Digest::Base");
143
+
144
+ cDigest_CRC32 = rb_define_class_under(mDigest, "CRC32", cDigest_Base);
145
+
146
+ rb_cvar_set(cDigest_CRC32, rb_intern("metadata"),
147
+ Data_Wrap_Struct(rb_cObject, 0, 0, &crc32));
148
+ }
149
+
150
+
@@ -0,0 +1,25 @@
1
+ #ifndef CRC32_INCLUDED
2
+ # define CRC32_INCLUDED
3
+
4
+ #include "defs.h"
5
+
6
+ typedef struct crc32_state_s {
7
+ uint32_t count[2]; /* message length in bits, lsw first */
8
+ uint32_t state[1]; /* digest buffer */
9
+ } CRC32_CTX;
10
+
11
+ #ifdef RUBY
12
+ #define CRC32_Init rb_Digest_CRC32_Init
13
+ #define CRC32_Update rb_Digest_CRC32_Update
14
+ #define CRC32_Finish rb_Digest_CRC32_Finish
15
+ #endif
16
+
17
+ int CRC32_Init _((CRC32_CTX *pms));
18
+ void CRC32_Update _((CRC32_CTX *pms, const uint8_t *data, size_t nbytes));
19
+ int CRC32_Finish _((CRC32_CTX *pms, uint8_t *digest));
20
+
21
+ #define CRC32_BLOCK_LENGTH 64
22
+ #define CRC32_DIGEST_LENGTH 4
23
+ #define CRC32_DIGEST_STRING_LENGTH (CRC32_DIGEST_LENGTH * 2 + 1)
24
+
25
+ #endif /* CRC32_INCLUDED */
@@ -0,0 +1,33 @@
1
+ #ifndef DEFS_H
2
+ #define DEFS_H
3
+
4
+ #include "ruby.h"
5
+ #include <sys/types.h>
6
+
7
+ #if defined(HAVE_SYS_CDEFS_H)
8
+ # include <sys/cdefs.h>
9
+ #endif
10
+ #if !defined(__BEGIN_DECLS)
11
+ # define __BEGIN_DECLS
12
+ # define __END_DECLS
13
+ #endif
14
+
15
+ #if defined(HAVE_INTTYPES_H)
16
+ # include <inttypes.h>
17
+ #else
18
+ typedef unsigned char uint8_t;
19
+ typedef unsigned int uint32_t;
20
+ # if SIZEOF_LONG == 8
21
+ typedef unsigned long uint64_t;
22
+ # elif defined(__GNUC__)
23
+ typedef unsigned long long uint64_t;
24
+ # elif defined(_MSC_VER)
25
+ typedef unsigned _int64 uint64_t;
26
+ # elif defined(__BORLANDC__)
27
+ typedef unsigned __int64 uint64_t;
28
+ # else
29
+ # define NO_UINT64_T
30
+ # endif
31
+ #endif
32
+
33
+ #endif /* DEFS_H */
@@ -0,0 +1,35 @@
1
+ #include "ruby.h"
2
+
3
+ #define RUBY_DIGEST_API_VERSION 3
4
+
5
+ typedef int (*rb_digest_hash_init_func_t)(void *);
6
+ typedef void (*rb_digest_hash_update_func_t)(void *, unsigned char *, size_t);
7
+ typedef int (*rb_digest_hash_finish_func_t)(void *, unsigned char *);
8
+
9
+ typedef struct {
10
+ int api_version;
11
+ size_t digest_len;
12
+ size_t block_len;
13
+ size_t ctx_size;
14
+ rb_digest_hash_init_func_t init_func;
15
+ rb_digest_hash_update_func_t update_func;
16
+ rb_digest_hash_finish_func_t finish_func;
17
+ } rb_digest_metadata_t;
18
+
19
+ #define DEFINE_UPDATE_FUNC_FOR_UINT(name) \
20
+ void \
21
+ rb_digest_##name##_update(void *ctx, unsigned char *ptr, size_t size) \
22
+ { \
23
+ const unsigned int stride = 16384; \
24
+ \
25
+ for (; size > stride; size -= stride, ptr += stride) { \
26
+ name##_Update(ctx, ptr, stride); \
27
+ } \
28
+ if (size > 0) name##_Update(ctx, ptr, size); \
29
+ }
30
+
31
+ #define DEFINE_FINISH_FUNC_FROM_FINAL(name) \
32
+ int \
33
+ rb_digest_##name##_finish(void *ctx, unsigned char *ptr) \
34
+ { \
35
+ return name##_Final(ptr, ctx); \
@@ -0,0 +1,11 @@
1
+ require 'mkmf'
2
+
3
+ $defs << "-DHAVE_CONFIG_H"
4
+ $INCFLAGS << " -I$(srcdir)/.. -I$(hdrdir)/ruby"
5
+
6
+ $objs = [ "crc32.#{$OBJEXT}" ]
7
+
8
+ have_header('inttypes.h')
9
+ have_header('ruby/digest.h')
10
+
11
+ create_makefile('digest/crc32')
@@ -0,0 +1,3 @@
1
+ require 'digest/crc32.so'
2
+
3
+ require 'digest/crc32/version'
@@ -0,0 +1 @@
1
+ Digest::CRC32::VERSION = '0.1.0'
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: crcs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nikolay Norkin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake-compiler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.9'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.9'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ description: This gem contains C extension for calculating CRC32
70
+ email:
71
+ - n.e.norkin@gmail.com
72
+ executables: []
73
+ extensions:
74
+ - ext/digest/crc32/extconf.rb
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - ".rspec"
79
+ - Gemfile
80
+ - README.md
81
+ - Rakefile
82
+ - crcs.gemspec
83
+ - ext/digest/crc32/crc32.c
84
+ - ext/digest/crc32/crc32.h
85
+ - ext/digest/crc32/defs.h
86
+ - ext/digest/crc32/digest.h
87
+ - ext/digest/crc32/extconf.rb
88
+ - lib/crcs.rb
89
+ - lib/digest/crc32/version.rb
90
+ homepage: https://github.com/duderman/crcs
91
+ licenses:
92
+ - MIT
93
+ metadata: {}
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '2.2'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 2.4.5
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: CRC32 implementation for Ruby
114
+ test_files: []