digest 3.1.0-java
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.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +97 -0
- data/ext/java/org/jruby/ext/digest/BubbleBabble.java +119 -0
- data/ext/java/org/jruby/ext/digest/DigestLibrary.java +44 -0
- data/ext/java/org/jruby/ext/digest/MD5.java +41 -0
- data/ext/java/org/jruby/ext/digest/RMD160.java +41 -0
- data/ext/java/org/jruby/ext/digest/RubyDigest.java +498 -0
- data/ext/java/org/jruby/ext/digest/SHA1.java +41 -0
- data/ext/java/org/jruby/ext/digest/SHA2.java +41 -0
- data/ext/java/org/jruby/ext/digest/lib/digest/bubblebabble.rb +3 -0
- data/ext/java/org/jruby/ext/digest/lib/digest/loader.rb +3 -0
- data/ext/java/org/jruby/ext/digest/lib/digest/md5.rb +3 -0
- data/ext/java/org/jruby/ext/digest/lib/digest/rmd160.rb +3 -0
- data/ext/java/org/jruby/ext/digest/lib/digest/sha1.rb +3 -0
- data/ext/java/org/jruby/ext/digest/lib/digest/sha2/loader.rb +3 -0
- data/lib/digest/sha2.rb +142 -0
- data/lib/digest/version.rb +5 -0
- data/lib/digest.jar +0 -0
- data/lib/digest.rb +123 -0
- metadata +65 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a175b98d1a4a7d66bac0148da4d3516a70e125646e9b867bacd154fb05e4b4ef
|
4
|
+
data.tar.gz: 938ffb653c44c018d9f7c74703f5ee8a885e1f7dbf94270969e2c4c3ac959ba0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 610b1874d03ed4c45c7a0bc5706506021c8676393e70db96c0bc5e1f46c8f3fb1d1a99a4828ecbd32fea9459b52e4aba52113c0df09926c52b66c4c60015ffd5
|
7
|
+
data.tar.gz: 99d7714c5cf4f4e08331b920bc70efec0413384fb1e930125d238293d104c90421d4dbb12a12eb36026c5a10dc1bc40573930e761948ce7b9e09e7b0a94bdf75
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without
|
4
|
+
modification, are permitted provided that the following conditions
|
5
|
+
are met:
|
6
|
+
1. Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
2. Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
|
12
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
13
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
14
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
15
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
16
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
17
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
18
|
+
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
19
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
20
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
21
|
+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
22
|
+
SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
# Digest
|
2
|
+
|
3
|
+

|
4
|
+
|
5
|
+
This module provides a framework for message digest libraries.
|
6
|
+
|
7
|
+
You may want to look at OpenSSL::Digest as it supports more algorithms.
|
8
|
+
|
9
|
+
A cryptographic hash function is a procedure that takes data and returns a fixed bit string: the hash value, also known as _digest_. Hash functions are also called one-way functions, it is easy to compute a digest from a message, but it is infeasible to generate a message from a digest.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'digest'
|
17
|
+
```
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install digest
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
require 'digest'
|
31
|
+
|
32
|
+
# Compute a complete digest
|
33
|
+
Digest::SHA256.digest 'message' #=> "\xABS\n\x13\xE4Y..."
|
34
|
+
|
35
|
+
sha256 = Digest::SHA256.new
|
36
|
+
sha256.digest 'message' #=> "\xABS\n\x13\xE4Y..."
|
37
|
+
|
38
|
+
# Other encoding formats
|
39
|
+
Digest::SHA256.hexdigest 'message' #=> "ab530a13e459..."
|
40
|
+
Digest::SHA256.base64digest 'message' #=> "q1MKE+RZFJgr..."
|
41
|
+
|
42
|
+
# Compute digest by chunks
|
43
|
+
md5 = Digest::MD5.new
|
44
|
+
md5.update 'message1'
|
45
|
+
md5 << 'message2' # << is an alias for update
|
46
|
+
|
47
|
+
md5.hexdigest #=> "94af09c09bb9..."
|
48
|
+
|
49
|
+
# Compute digest for a file
|
50
|
+
sha256 = Digest::SHA256.file 'testfile'
|
51
|
+
sha256.hexdigest
|
52
|
+
```
|
53
|
+
|
54
|
+
Additionally digests can be encoded in "bubble babble" format as a sequence of consonants and vowels which is more recognizable and comparable than a hexadecimal digest.
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
require 'digest/bubblebabble'
|
58
|
+
|
59
|
+
Digest::SHA256.bubblebabble 'message' #=> "xopoh-fedac-fenyh-..."
|
60
|
+
```
|
61
|
+
|
62
|
+
See the bubble babble specification at http://web.mit.edu/kenta/www/one/bubblebabble/spec/jrtrjwzi/draft-huima-01.txt.
|
63
|
+
|
64
|
+
## Digest algorithms
|
65
|
+
|
66
|
+
Different digest algorithms (or hash functions) are available:
|
67
|
+
|
68
|
+
```
|
69
|
+
MD5::
|
70
|
+
See RFC 1321 The MD5 Message-Digest Algorithm
|
71
|
+
RIPEMD-160::
|
72
|
+
As Digest::RMD160.
|
73
|
+
See http://homes.esat.kuleuven.be/~bosselae/ripemd160.html.
|
74
|
+
SHA1::
|
75
|
+
See FIPS 180 Secure Hash Standard.
|
76
|
+
SHA2 family::
|
77
|
+
See FIPS 180 Secure Hash Standard which defines the following algorithms:
|
78
|
+
SHA512
|
79
|
+
SHA384
|
80
|
+
SHA256
|
81
|
+
```
|
82
|
+
|
83
|
+
The latest versions of the FIPS publications can be found here: http://csrc.nist.gov/publications/PubsFIPS.html.
|
84
|
+
|
85
|
+
## Development
|
86
|
+
|
87
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
88
|
+
|
89
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
90
|
+
|
91
|
+
## Contributing
|
92
|
+
|
93
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/digest.
|
94
|
+
|
95
|
+
## License
|
96
|
+
|
97
|
+
The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause).
|
@@ -0,0 +1,119 @@
|
|
1
|
+
/*
|
2
|
+
**** BEGIN LICENSE BLOCK *****
|
3
|
+
* BSD 2-Clause License
|
4
|
+
*
|
5
|
+
* Copyright (c) 2010, Charles Oliver Nutter <headius@headius.com>
|
6
|
+
* All rights reserved.
|
7
|
+
*
|
8
|
+
* Redistribution and use in source and binary forms, with or without
|
9
|
+
* modification, are permitted provided that the following conditions are met:
|
10
|
+
*
|
11
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
12
|
+
* list of conditions and the following disclaimer.
|
13
|
+
*
|
14
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
15
|
+
* this list of conditions and the following disclaimer in the documentation
|
16
|
+
* and/or other materials provided with the distribution.
|
17
|
+
*
|
18
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
***** END LICENSE BLOCK *****/
|
29
|
+
|
30
|
+
package org.jruby.ext.digest;
|
31
|
+
|
32
|
+
import org.jruby.Ruby;
|
33
|
+
import org.jruby.runtime.load.Library;
|
34
|
+
import org.jruby.util.ByteList;
|
35
|
+
|
36
|
+
import java.io.IOException;
|
37
|
+
|
38
|
+
public class BubbleBabble implements Library {
|
39
|
+
|
40
|
+
public void load(final Ruby runtime, boolean wrap) throws IOException {
|
41
|
+
RubyDigest.createDigestBubbleBabble(runtime);
|
42
|
+
}
|
43
|
+
|
44
|
+
/**
|
45
|
+
* Ported from OpenSSH (https://github.com/openssh/openssh-portable/blob/957fbceb0f3166e41b76fdb54075ab3b9cc84cba/sshkey.c#L942-L987)
|
46
|
+
*
|
47
|
+
* OpenSSH License Notice
|
48
|
+
*
|
49
|
+
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
50
|
+
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
|
51
|
+
* Copyright (c) 2010,2011 Damien Miller. All rights reserved.
|
52
|
+
*
|
53
|
+
* Redistribution and use in source and binary forms, with or without
|
54
|
+
* modification, are permitted provided that the following conditions
|
55
|
+
* are met:
|
56
|
+
* 1. Redistributions of source code must retain the above copyright
|
57
|
+
* notice, this list of conditions and the following disclaimer.
|
58
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
59
|
+
* notice, this list of conditions and the following disclaimer in the
|
60
|
+
* documentation and/or other materials provided with the distribution.
|
61
|
+
*
|
62
|
+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
63
|
+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
64
|
+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
65
|
+
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
66
|
+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
67
|
+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
68
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
69
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
70
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
71
|
+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
72
|
+
*/
|
73
|
+
public static ByteList bubblebabble(byte[] message, int begin, int length) {
|
74
|
+
char[] vowels = new char[]{'a', 'e', 'i', 'o', 'u', 'y'};
|
75
|
+
char[] consonants = new char[]{'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
|
76
|
+
'n', 'p', 'r', 's', 't', 'v', 'z', 'x'};
|
77
|
+
|
78
|
+
long seed = 1;
|
79
|
+
|
80
|
+
ByteList retval = new ByteList();
|
81
|
+
|
82
|
+
int rounds = (length / 2) + 1;
|
83
|
+
retval.append('x');
|
84
|
+
for (int i = 0; i < rounds; i++) {
|
85
|
+
int idx0, idx1, idx2, idx3, idx4;
|
86
|
+
|
87
|
+
if ((i + 1 < rounds) || (length % 2 != 0)) {
|
88
|
+
long b = message[begin + 2 * i] & 0xFF;
|
89
|
+
idx0 = (int) ((((b >> 6) & 3) + seed) % 6) & 0xFFFFFFFF;
|
90
|
+
idx1 = (int) (((b) >> 2) & 15) & 0xFFFFFFFF;
|
91
|
+
idx2 = (int) (((b & 3) + (seed / 6)) % 6) & 0xFFFFFFFF;
|
92
|
+
retval.append(vowels[idx0]);
|
93
|
+
retval.append(consonants[idx1]);
|
94
|
+
retval.append(vowels[idx2]);
|
95
|
+
if ((i + 1) < rounds) {
|
96
|
+
long b2 = message[begin + (2 * i) + 1] & 0xFF;
|
97
|
+
idx3 = (int) ((b2 >> 4) & 15) & 0xFFFFFFFF;
|
98
|
+
idx4 = (int) ((b2) & 15) & 0xFFFFFFFF;
|
99
|
+
retval.append(consonants[idx3]);
|
100
|
+
retval.append('-');
|
101
|
+
retval.append(consonants[idx4]);
|
102
|
+
seed = ((seed * 5) +
|
103
|
+
((b * 7) +
|
104
|
+
b2)) % 36;
|
105
|
+
}
|
106
|
+
} else {
|
107
|
+
idx0 = (int) (seed % 6) & 0xFFFFFFFF;
|
108
|
+
idx1 = 16;
|
109
|
+
idx2 = (int) (seed / 6) & 0xFFFFFFFF;
|
110
|
+
retval.append(vowels[idx0]);
|
111
|
+
retval.append(consonants[idx1]);
|
112
|
+
retval.append(vowels[idx2]);
|
113
|
+
}
|
114
|
+
}
|
115
|
+
retval.append('x');
|
116
|
+
|
117
|
+
return retval;
|
118
|
+
}
|
119
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
/*
|
2
|
+
**** BEGIN LICENSE BLOCK *****
|
3
|
+
* BSD 2-Clause License
|
4
|
+
*
|
5
|
+
* Copyright (C) 2006 Ola Bini <ola@ologix.com>
|
6
|
+
* All rights reserved.
|
7
|
+
*
|
8
|
+
* Redistribution and use in source and binary forms, with or without
|
9
|
+
* modification, are permitted provided that the following conditions are met:
|
10
|
+
*
|
11
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
12
|
+
* list of conditions and the following disclaimer.
|
13
|
+
*
|
14
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
15
|
+
* this list of conditions and the following disclaimer in the documentation
|
16
|
+
* and/or other materials provided with the distribution.
|
17
|
+
*
|
18
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
***** END LICENSE BLOCK *****/
|
29
|
+
|
30
|
+
package org.jruby.ext.digest;
|
31
|
+
|
32
|
+
import java.io.IOException;
|
33
|
+
|
34
|
+
import org.jruby.Ruby;
|
35
|
+
import org.jruby.runtime.load.Library;
|
36
|
+
|
37
|
+
/**
|
38
|
+
* @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
|
39
|
+
*/
|
40
|
+
public class DigestLibrary implements Library {
|
41
|
+
public void load(final Ruby runtime, boolean wrap) throws IOException {
|
42
|
+
org.jruby.ext.digest.RubyDigest.createDigest(runtime);
|
43
|
+
}
|
44
|
+
}// DigestLibrary
|
@@ -0,0 +1,41 @@
|
|
1
|
+
/*
|
2
|
+
**** BEGIN LICENSE BLOCK *****
|
3
|
+
* BSD 2-Clause License
|
4
|
+
*
|
5
|
+
* Copyright (c) 2010, Charles Oliver Nutter <headius@headius.com>
|
6
|
+
* All rights reserved.
|
7
|
+
*
|
8
|
+
* Redistribution and use in source and binary forms, with or without
|
9
|
+
* modification, are permitted provided that the following conditions are met:
|
10
|
+
*
|
11
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
12
|
+
* list of conditions and the following disclaimer.
|
13
|
+
*
|
14
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
15
|
+
* this list of conditions and the following disclaimer in the documentation
|
16
|
+
* and/or other materials provided with the distribution.
|
17
|
+
*
|
18
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
***** END LICENSE BLOCK *****/
|
29
|
+
|
30
|
+
package org.jruby.ext.digest;
|
31
|
+
|
32
|
+
import java.io.IOException;
|
33
|
+
import org.jruby.Ruby;
|
34
|
+
import org.jruby.runtime.load.Library;
|
35
|
+
|
36
|
+
public class MD5 implements Library {
|
37
|
+
|
38
|
+
public void load(final Ruby runtime, boolean wrap) throws IOException {
|
39
|
+
org.jruby.ext.digest.RubyDigest.createDigestMD5(runtime);
|
40
|
+
}
|
41
|
+
}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
/*
|
2
|
+
**** BEGIN LICENSE BLOCK *****
|
3
|
+
* BSD 2-Clause License
|
4
|
+
*
|
5
|
+
* Copyright (c) 2010, Charles Oliver Nutter <headius@headius.com>
|
6
|
+
* All rights reserved.
|
7
|
+
*
|
8
|
+
* Redistribution and use in source and binary forms, with or without
|
9
|
+
* modification, are permitted provided that the following conditions are met:
|
10
|
+
*
|
11
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
12
|
+
* list of conditions and the following disclaimer.
|
13
|
+
*
|
14
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
15
|
+
* this list of conditions and the following disclaimer in the documentation
|
16
|
+
* and/or other materials provided with the distribution.
|
17
|
+
*
|
18
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
***** END LICENSE BLOCK *****/
|
29
|
+
|
30
|
+
package org.jruby.ext.digest;
|
31
|
+
|
32
|
+
import java.io.IOException;
|
33
|
+
import org.jruby.Ruby;
|
34
|
+
import org.jruby.runtime.load.Library;
|
35
|
+
|
36
|
+
public class RMD160 implements Library {
|
37
|
+
|
38
|
+
public void load(final Ruby runtime, boolean wrap) throws IOException {
|
39
|
+
org.jruby.ext.digest.RubyDigest.createDigestRMD160(runtime);
|
40
|
+
}
|
41
|
+
}
|
@@ -0,0 +1,498 @@
|
|
1
|
+
/*
|
2
|
+
**** BEGIN LICENSE BLOCK *****
|
3
|
+
* BSD 2-Clause License
|
4
|
+
*
|
5
|
+
* Copyright (C) 2006, 2007 Ola Bini <ola@ologix.com>
|
6
|
+
* Copyright (C) 2007 Nick Sieger <nicksieger@gmail.com>
|
7
|
+
* Copyright (C) 2008 Vladimir Sizikov <vsizikov@gmail.com>
|
8
|
+
* Copyright (C) 2009 Joseph LaFata <joe@quibb.org>
|
9
|
+
* All rights reserved.
|
10
|
+
*
|
11
|
+
* Redistribution and use in source and binary forms, with or without
|
12
|
+
* modification, are permitted provided that the following conditions are met:
|
13
|
+
*
|
14
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
15
|
+
* list of conditions and the following disclaimer.
|
16
|
+
*
|
17
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
18
|
+
* this list of conditions and the following disclaimer in the documentation
|
19
|
+
* and/or other materials provided with the distribution.
|
20
|
+
*
|
21
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
22
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
23
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
24
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
25
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
26
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
27
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
28
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
29
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
***** END LICENSE BLOCK *****/
|
32
|
+
|
33
|
+
package org.jruby.ext.digest;
|
34
|
+
|
35
|
+
import java.security.MessageDigest;
|
36
|
+
import java.security.NoSuchAlgorithmException;
|
37
|
+
import java.security.Provider;
|
38
|
+
import java.util.HashMap;
|
39
|
+
import java.util.Map;
|
40
|
+
|
41
|
+
import org.jcodings.specific.USASCIIEncoding;
|
42
|
+
import org.jruby.Ruby;
|
43
|
+
import org.jruby.RubyClass;
|
44
|
+
import org.jruby.RubyFixnum;
|
45
|
+
import org.jruby.RubyModule;
|
46
|
+
import org.jruby.RubyObject;
|
47
|
+
import org.jruby.RubyString;
|
48
|
+
|
49
|
+
import org.jruby.anno.JRubyClass;
|
50
|
+
import org.jruby.anno.JRubyMethod;
|
51
|
+
import org.jruby.anno.JRubyModule;
|
52
|
+
import org.jruby.exceptions.RaiseException;
|
53
|
+
import org.jruby.runtime.Block;
|
54
|
+
import org.jruby.runtime.ThreadContext;
|
55
|
+
import org.jruby.runtime.Visibility;
|
56
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
57
|
+
import org.jruby.util.ArraySupport;
|
58
|
+
import org.jruby.util.ByteList;
|
59
|
+
import org.jruby.util.log.Logger;
|
60
|
+
import org.jruby.util.log.LoggerFactory;
|
61
|
+
|
62
|
+
/**
|
63
|
+
* @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
|
64
|
+
*/
|
65
|
+
@JRubyModule(name="Digest")
|
66
|
+
public class RubyDigest {
|
67
|
+
|
68
|
+
private static final Map<String, MessageDigest> CLONEABLE_DIGESTS = new HashMap<String, MessageDigest>(8, 1);
|
69
|
+
static {
|
70
|
+
// standard digests from JCA specification; if we can retrieve and clone, save them
|
71
|
+
for (String name : new String[] {"MD2", "MD5", "SHA-1", "SHA-256", "SHA-384", "SHA-512"}) {
|
72
|
+
try {
|
73
|
+
MessageDigest digest = MessageDigest.getInstance(name);
|
74
|
+
digest.clone();
|
75
|
+
CLONEABLE_DIGESTS.put(name, digest);
|
76
|
+
}
|
77
|
+
catch (Exception e) {
|
78
|
+
logger().debug(name + " not clonable", e);
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
private static Logger logger() { return LoggerFactory.getLogger(RubyDigest.class); }
|
84
|
+
|
85
|
+
private static final String PROVIDER = "org.bouncycastle.jce.provider.BouncyCastleProvider";
|
86
|
+
private static Provider provider = null;
|
87
|
+
|
88
|
+
public static void createDigest(Ruby runtime) {
|
89
|
+
try {
|
90
|
+
provider = (Provider) Class.forName(PROVIDER).getConstructor().newInstance();
|
91
|
+
}
|
92
|
+
catch (Throwable t) { /* provider is not available */ }
|
93
|
+
|
94
|
+
RubyModule mDigest = runtime.defineModule("Digest");
|
95
|
+
mDigest.defineAnnotatedMethods(RubyDigest.class);
|
96
|
+
RubyModule mDigestInstance = mDigest.defineModuleUnder("Instance");
|
97
|
+
mDigestInstance.defineAnnotatedMethods(DigestInstance.class);
|
98
|
+
RubyClass cDigestClass = mDigest.defineClassUnder("Class", runtime.getObject(), DigestClass::new);
|
99
|
+
cDigestClass.defineAnnotatedMethods(DigestClass.class);
|
100
|
+
cDigestClass.includeModule(mDigestInstance);
|
101
|
+
RubyClass cDigestBase = mDigest.defineClassUnder("Base", cDigestClass, DigestBase::new);
|
102
|
+
cDigestBase.defineAnnotatedMethods(DigestBase.class);
|
103
|
+
}
|
104
|
+
|
105
|
+
private static MessageDigest createMessageDigest(final String name) throws NoSuchAlgorithmException {
|
106
|
+
MessageDigest cloneable = CLONEABLE_DIGESTS.get(name);
|
107
|
+
if (cloneable != null) {
|
108
|
+
try {
|
109
|
+
return (MessageDigest) cloneable.clone();
|
110
|
+
}
|
111
|
+
catch (CloneNotSupportedException e) {
|
112
|
+
// should never happen, since we tested it in static init
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
// fall back on JCA mechanisms for getting a digest
|
117
|
+
if (provider != null) {
|
118
|
+
try {
|
119
|
+
return MessageDigest.getInstance(name, provider);
|
120
|
+
}
|
121
|
+
catch (NoSuchAlgorithmException e) {
|
122
|
+
// bouncy castle doesn't support algorithm
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
// fall back to default JCA providers
|
127
|
+
return MessageDigest.getInstance(name);
|
128
|
+
}
|
129
|
+
|
130
|
+
private final static byte[] digits = {
|
131
|
+
'0', '1', '2', '3', '4', '5',
|
132
|
+
'6', '7', '8', '9', 'a', 'b',
|
133
|
+
'c', 'd', 'e', 'f', 'g', 'h',
|
134
|
+
'i', 'j', 'k', 'l', 'm', 'n',
|
135
|
+
'o', 'p', 'q', 'r', 's', 't',
|
136
|
+
'u', 'v', 'w', 'x', 'y', 'z'
|
137
|
+
};
|
138
|
+
|
139
|
+
private static ByteList toHex(byte[] val) {
|
140
|
+
ByteList byteList = new ByteList(val.length * 2);
|
141
|
+
for (int i = 0, j = val.length; i < j; i++) {
|
142
|
+
int b = val[i] & 0xFF;
|
143
|
+
byteList.append(digits[b >> 4]);
|
144
|
+
byteList.append(digits[b & 0xF]);
|
145
|
+
}
|
146
|
+
return byteList;
|
147
|
+
}
|
148
|
+
|
149
|
+
private static RubyString toHexString(Ruby runtime, byte[] val) {
|
150
|
+
return RubyString.newStringNoCopy(runtime, new ByteList(ByteList.plain(toHex(val)), USASCIIEncoding.INSTANCE));
|
151
|
+
}
|
152
|
+
|
153
|
+
@JRubyMethod(name = "hexencode", required = 1, meta = true)
|
154
|
+
public static RubyString hexencode(IRubyObject self, IRubyObject arg) {
|
155
|
+
return toHexString(self.getRuntime(), arg.convertToString().getBytes());
|
156
|
+
}
|
157
|
+
|
158
|
+
@JRubyMethod(name = "bubblebabble", required = 1, meta = true)
|
159
|
+
public static RubyString bubblebabble(IRubyObject recv, IRubyObject arg) {
|
160
|
+
final ByteList bytes = arg.convertToString().getByteList();
|
161
|
+
return RubyString.newString(recv.getRuntime(), BubbleBabble.bubblebabble(bytes.unsafeBytes(), bytes.begin(), bytes.length()));
|
162
|
+
}
|
163
|
+
|
164
|
+
private static class Metadata {
|
165
|
+
|
166
|
+
private final String name;
|
167
|
+
private final int blockLength;
|
168
|
+
|
169
|
+
Metadata(String name, int blockLength) {
|
170
|
+
this.name = name;
|
171
|
+
this.blockLength = blockLength;
|
172
|
+
}
|
173
|
+
|
174
|
+
String getName() {
|
175
|
+
return name;
|
176
|
+
}
|
177
|
+
|
178
|
+
int getBlockLength() {
|
179
|
+
return blockLength;
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
|
184
|
+
@JRubyClass(name="Digest::MD5", parent="Digest::Base")
|
185
|
+
public static class MD5 {}
|
186
|
+
@JRubyClass(name="Digest::RMD160", parent="Digest::Base")
|
187
|
+
public static class RMD160 {}
|
188
|
+
@JRubyClass(name="Digest::SHA1", parent="Digest::Base")
|
189
|
+
public static class SHA1 {}
|
190
|
+
@JRubyClass(name="Digest::SHA256", parent="Digest::Base")
|
191
|
+
public static class SHA256 {}
|
192
|
+
@JRubyClass(name="Digest::SHA384", parent="Digest::Base")
|
193
|
+
public static class SHA384 {}
|
194
|
+
@JRubyClass(name="Digest::SHA512", parent="Digest::Base")
|
195
|
+
public static class SHA512 {}
|
196
|
+
|
197
|
+
public static void createDigestMD5(Ruby runtime) {
|
198
|
+
runtime.getLoadService().require("digest");
|
199
|
+
RubyModule Digest = runtime.getModule("Digest");
|
200
|
+
RubyClass Base = Digest.getClass("Base");
|
201
|
+
RubyClass MD5 = Digest.defineClassUnder("MD5", Base, Base.getAllocator());
|
202
|
+
MD5.setInternalVariable("metadata", new Metadata("MD5", 64));
|
203
|
+
}
|
204
|
+
|
205
|
+
public static void createDigestRMD160(Ruby runtime) {
|
206
|
+
runtime.getLoadService().require("digest");
|
207
|
+
if(provider == null) {
|
208
|
+
throw runtime.newLoadError("RMD160 not supported without BouncyCastle");
|
209
|
+
}
|
210
|
+
RubyModule Digest = runtime.getModule("Digest");
|
211
|
+
RubyClass Base = Digest.getClass("Base");
|
212
|
+
RubyClass RMD160 = Digest.defineClassUnder("RMD160", Base, Base.getAllocator());
|
213
|
+
RMD160.setInternalVariable("metadata", new Metadata("RIPEMD160", 64));
|
214
|
+
}
|
215
|
+
|
216
|
+
public static void createDigestSHA1(Ruby runtime) {
|
217
|
+
runtime.getLoadService().require("digest");
|
218
|
+
RubyModule Digest = runtime.getModule("Digest");
|
219
|
+
RubyClass Base = Digest.getClass("Base");
|
220
|
+
RubyClass SHA1 = Digest.defineClassUnder("SHA1", Base, Base.getAllocator());
|
221
|
+
SHA1.setInternalVariable("metadata", new Metadata("SHA1", 64));
|
222
|
+
}
|
223
|
+
|
224
|
+
public static void createDigestSHA2(Ruby runtime) {
|
225
|
+
runtime.getLoadService().require("digest");
|
226
|
+
try {
|
227
|
+
createMessageDigest("SHA-256");
|
228
|
+
}
|
229
|
+
catch (NoSuchAlgorithmException e) {
|
230
|
+
RaiseException ex = runtime.newLoadError("SHA2 not supported");
|
231
|
+
ex.initCause(e);
|
232
|
+
throw ex;
|
233
|
+
}
|
234
|
+
final RubyModule Digest = runtime.getModule("Digest");
|
235
|
+
final RubyClass Base = Digest.getClass("Base");
|
236
|
+
RubyClass SHA256 = Digest.defineClassUnder("SHA256", Base, Base.getAllocator());
|
237
|
+
SHA256.setInternalVariable("metadata", new Metadata("SHA-256", 64));
|
238
|
+
RubyClass SHA384 = Digest.defineClassUnder("SHA384", Base, Base.getAllocator());
|
239
|
+
SHA384.setInternalVariable("metadata", new Metadata("SHA-384", 128));
|
240
|
+
RubyClass SHA512 = Digest.defineClassUnder("SHA512", Base, Base.getAllocator());
|
241
|
+
SHA512.setInternalVariable("metadata", new Metadata("SHA-512", 128));
|
242
|
+
}
|
243
|
+
|
244
|
+
public static void createDigestBubbleBabble(Ruby runtime) {
|
245
|
+
runtime.getLoadService().require("digest");
|
246
|
+
RubyModule Digest = runtime.getModule("Digest");
|
247
|
+
RubyClass Base = Digest.getClass("Base");
|
248
|
+
RubyClass MD5 = Digest.defineClassUnder("BubbleBabble", Base, Base.getAllocator());
|
249
|
+
MD5.setInternalVariable("metadata", new Metadata("BubbleBabble", 64));
|
250
|
+
}
|
251
|
+
|
252
|
+
@JRubyModule(name = "Digest::Instance")
|
253
|
+
public static class DigestInstance {
|
254
|
+
|
255
|
+
private static IRubyObject throwUnimplError(IRubyObject self, String name) {
|
256
|
+
throw self.getRuntime().newRuntimeError(String.format("%s does not implement %s()", self.getMetaClass().getRealClass().getName(), name));
|
257
|
+
}
|
258
|
+
|
259
|
+
/* instance methods that should be overridden */
|
260
|
+
@JRubyMethod(name = {"update", "<<"}, required = 1)
|
261
|
+
public static IRubyObject update(ThreadContext context, IRubyObject self, IRubyObject arg) {
|
262
|
+
return throwUnimplError(self, "update");
|
263
|
+
}
|
264
|
+
|
265
|
+
@JRubyMethod()
|
266
|
+
public static IRubyObject finish(ThreadContext context, IRubyObject self) {
|
267
|
+
return throwUnimplError(self, "finish");
|
268
|
+
}
|
269
|
+
|
270
|
+
@JRubyMethod()
|
271
|
+
public static IRubyObject reset(ThreadContext context, IRubyObject self) {
|
272
|
+
return throwUnimplError(self, "reset");
|
273
|
+
}
|
274
|
+
|
275
|
+
@JRubyMethod()
|
276
|
+
public static IRubyObject digest_length(ThreadContext context, IRubyObject self) {
|
277
|
+
return digest(context, self, null).convertToString().bytesize();
|
278
|
+
}
|
279
|
+
|
280
|
+
@JRubyMethod()
|
281
|
+
public static IRubyObject block_length(ThreadContext context, IRubyObject self) {
|
282
|
+
return throwUnimplError(self, "block_length");
|
283
|
+
}
|
284
|
+
|
285
|
+
/* instance methods that may be overridden */
|
286
|
+
@JRubyMethod(name = "==", required = 1)
|
287
|
+
public static IRubyObject op_equal(ThreadContext context, IRubyObject self, IRubyObject oth) {
|
288
|
+
if(oth.isNil()) return context.fals;
|
289
|
+
|
290
|
+
RubyString str1, str2;
|
291
|
+
RubyModule instance = (RubyModule)context.runtime.getModule("Digest").getConstantAt("Instance");
|
292
|
+
if (oth.getMetaClass().getRealClass().hasModuleInHierarchy(instance)) {
|
293
|
+
str1 = digest(context, self, null).convertToString();
|
294
|
+
str2 = digest(context, oth, null).convertToString();
|
295
|
+
} else {
|
296
|
+
str1 = to_s(context, self).convertToString();
|
297
|
+
str2 = oth.convertToString();
|
298
|
+
}
|
299
|
+
boolean ret = str1.bytesize().eql(str2.bytesize()) && (str1.eql(str2));
|
300
|
+
return ret ? context.tru : context.fals;
|
301
|
+
}
|
302
|
+
|
303
|
+
@JRubyMethod()
|
304
|
+
public static IRubyObject inspect(ThreadContext context, IRubyObject self) {
|
305
|
+
return RubyString.newStringNoCopy(self.getRuntime(), ByteList.plain("#<" + self.getMetaClass().getRealClass().getName() + ": " + hexdigest(context, self, null) + ">"));
|
306
|
+
}
|
307
|
+
|
308
|
+
/* instance methods that need not usually be overridden */
|
309
|
+
@JRubyMethod(name = "new")
|
310
|
+
public static IRubyObject newObject(ThreadContext context, IRubyObject self) {
|
311
|
+
return self.rbClone().callMethod(context, "reset");
|
312
|
+
}
|
313
|
+
|
314
|
+
@JRubyMethod(optional = 1)
|
315
|
+
public static IRubyObject digest(ThreadContext context, IRubyObject self, IRubyObject[] args) {
|
316
|
+
final IRubyObject value;
|
317
|
+
if (args != null && args.length > 0) {
|
318
|
+
self.callMethod(context, "reset");
|
319
|
+
self.callMethod(context, "update", args[0]);
|
320
|
+
value = self.callMethod(context, "finish");
|
321
|
+
self.callMethod(context, "reset");
|
322
|
+
} else {
|
323
|
+
IRubyObject clone = self.rbClone();
|
324
|
+
value = clone.callMethod(context, "finish");
|
325
|
+
clone.callMethod(context, "reset");
|
326
|
+
}
|
327
|
+
return value;
|
328
|
+
}
|
329
|
+
|
330
|
+
@JRubyMethod(name = "digest!")
|
331
|
+
public static IRubyObject digest_bang(ThreadContext context, IRubyObject self) {
|
332
|
+
IRubyObject value = self.callMethod(context, "finish");
|
333
|
+
self.callMethod(context, "reset");
|
334
|
+
return value;
|
335
|
+
}
|
336
|
+
|
337
|
+
@JRubyMethod(optional = 1)
|
338
|
+
public static IRubyObject hexdigest(ThreadContext context, IRubyObject self, IRubyObject[] args) {
|
339
|
+
return toHexString(context.runtime, digest(context, self, args).convertToString().getBytes());
|
340
|
+
}
|
341
|
+
|
342
|
+
@JRubyMethod(name = "hexdigest!")
|
343
|
+
public static IRubyObject hexdigest_bang(ThreadContext context, IRubyObject self) {
|
344
|
+
return toHexString(context.runtime, digest_bang(context, self).convertToString().getBytes());
|
345
|
+
}
|
346
|
+
|
347
|
+
@JRubyMethod(name = "bubblebabble", required = 1, optional = 1, meta = true)
|
348
|
+
public static IRubyObject bubblebabble(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block unusedBlock) {
|
349
|
+
byte[] digest = recv.callMethod(context, "digest", args, Block.NULL_BLOCK).convertToString().getBytes();
|
350
|
+
return RubyString.newString(recv.getRuntime(), BubbleBabble.bubblebabble(digest, 0, digest.length));
|
351
|
+
}
|
352
|
+
|
353
|
+
@JRubyMethod()
|
354
|
+
public static IRubyObject to_s(ThreadContext context, IRubyObject self) {
|
355
|
+
return self.callMethod(context, "hexdigest");
|
356
|
+
}
|
357
|
+
|
358
|
+
@JRubyMethod(name = {"length", "size"})
|
359
|
+
public static IRubyObject length(ThreadContext context, IRubyObject self) {
|
360
|
+
return self.callMethod(context, "digest_length");
|
361
|
+
}
|
362
|
+
}
|
363
|
+
|
364
|
+
|
365
|
+
@JRubyClass(name="Digest::Class")
|
366
|
+
public static class DigestClass extends RubyObject {
|
367
|
+
public DigestClass(Ruby runtime, RubyClass type) {
|
368
|
+
super(runtime, type);
|
369
|
+
}
|
370
|
+
|
371
|
+
@JRubyMethod(name = "digest", required = 1, rest = true, meta = true)
|
372
|
+
public static IRubyObject s_digest(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block unusedBlock) {
|
373
|
+
final Ruby runtime = context.runtime;
|
374
|
+
if (args.length < 1) {
|
375
|
+
throw runtime.newArgumentError("no data given");
|
376
|
+
}
|
377
|
+
RubyString str = args[0].convertToString();
|
378
|
+
args = ArraySupport.newCopy(args, 1, args.length - 1); // skip first arg
|
379
|
+
IRubyObject obj = ((RubyClass) recv).newInstance(context, args, Block.NULL_BLOCK);
|
380
|
+
return obj.callMethod(context, "digest", str);
|
381
|
+
}
|
382
|
+
|
383
|
+
@JRubyMethod(name = "hexdigest", required = 1, optional = 1, meta = true)
|
384
|
+
public static IRubyObject s_hexdigest(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block unusedBlock) {
|
385
|
+
Ruby runtime = recv.getRuntime();
|
386
|
+
byte[] digest = recv.callMethod(context, "digest", args, Block.NULL_BLOCK).convertToString().getBytes();
|
387
|
+
return RubyDigest.toHexString(runtime, digest);
|
388
|
+
}
|
389
|
+
|
390
|
+
@JRubyMethod(name = "bubblebabble", required = 1, meta = true)
|
391
|
+
public static RubyString bubblebabble(IRubyObject recv, IRubyObject arg) {
|
392
|
+
byte[] digest = recv.callMethod(recv.getRuntime().getCurrentContext(), "digest", arg).convertToString().getBytes();
|
393
|
+
return RubyString.newString(recv.getRuntime(), BubbleBabble.bubblebabble(digest, 0, digest.length));
|
394
|
+
}
|
395
|
+
}
|
396
|
+
|
397
|
+
|
398
|
+
@JRubyClass(name="Digest::Base")
|
399
|
+
public static class DigestBase extends RubyObject {
|
400
|
+
private MessageDigest algo;
|
401
|
+
private int blockLength = 0;
|
402
|
+
|
403
|
+
public DigestBase(Ruby runtime, RubyClass type) {
|
404
|
+
super(runtime,type);
|
405
|
+
|
406
|
+
if(type == runtime.getModule("Digest").getClass("Base")) {
|
407
|
+
throw runtime.newNotImplementedError("Digest::Base is an abstract class");
|
408
|
+
}
|
409
|
+
|
410
|
+
Metadata metadata = getMetadata(type);
|
411
|
+
if(metadata == null) {
|
412
|
+
throw runtime.newNotImplementedError("the " + type + "() function is unimplemented on this machine");
|
413
|
+
}
|
414
|
+
|
415
|
+
try {
|
416
|
+
setAlgorithm(metadata);
|
417
|
+
} catch(NoSuchAlgorithmException e) {
|
418
|
+
throw runtime.newNotImplementedError("the " + type + "() function is unimplemented on this machine");
|
419
|
+
}
|
420
|
+
|
421
|
+
}
|
422
|
+
|
423
|
+
// if subclass extends particular digest we need to walk to find it...we should rearchitect digest to avoid walking type systems
|
424
|
+
private Metadata getMetadata(RubyModule type) {
|
425
|
+
for (RubyModule current = type; current != null; current = current.getSuperClass()) {
|
426
|
+
Metadata metadata = (Metadata) current.getInternalVariable("metadata");
|
427
|
+
|
428
|
+
if (metadata != null) return metadata;
|
429
|
+
}
|
430
|
+
|
431
|
+
return null;
|
432
|
+
}
|
433
|
+
|
434
|
+
@JRubyMethod(required = 1, visibility = Visibility.PRIVATE)
|
435
|
+
@Override
|
436
|
+
public IRubyObject initialize_copy(IRubyObject obj) {
|
437
|
+
if (this == obj) return this;
|
438
|
+
|
439
|
+
DigestBase from = (DigestBase) obj;
|
440
|
+
from.checkFrozen();
|
441
|
+
|
442
|
+
try {
|
443
|
+
this.algo = (MessageDigest) from.algo.clone();
|
444
|
+
}
|
445
|
+
catch (CloneNotSupportedException e) {
|
446
|
+
String name = from.algo.getAlgorithm();
|
447
|
+
throw getRuntime().newTypeError("Could not initialize copy of digest (" + name + ")");
|
448
|
+
}
|
449
|
+
return this;
|
450
|
+
}
|
451
|
+
|
452
|
+
@JRubyMethod(name = {"update", "<<"}, required = 1)
|
453
|
+
public IRubyObject update(IRubyObject obj) {
|
454
|
+
ByteList bytes = obj.convertToString().getByteList();
|
455
|
+
algo.update(bytes.getUnsafeBytes(), bytes.getBegin(), bytes.getRealSize());
|
456
|
+
return this;
|
457
|
+
}
|
458
|
+
|
459
|
+
@JRubyMethod()
|
460
|
+
public IRubyObject finish() {
|
461
|
+
IRubyObject digest = RubyString.newStringNoCopy(getRuntime(), algo.digest());
|
462
|
+
algo.reset();
|
463
|
+
return digest;
|
464
|
+
}
|
465
|
+
|
466
|
+
@JRubyMethod()
|
467
|
+
public IRubyObject digest_length() {
|
468
|
+
return RubyFixnum.newFixnum(getRuntime(), algo.getDigestLength());
|
469
|
+
}
|
470
|
+
|
471
|
+
@JRubyMethod()
|
472
|
+
public IRubyObject block_length() {
|
473
|
+
if (blockLength == 0) {
|
474
|
+
throw getRuntime().newRuntimeError(
|
475
|
+
this.getMetaClass() + " doesn't implement block_length()");
|
476
|
+
}
|
477
|
+
return RubyFixnum.newFixnum(getRuntime(), blockLength);
|
478
|
+
}
|
479
|
+
|
480
|
+
@JRubyMethod()
|
481
|
+
public IRubyObject reset() {
|
482
|
+
algo.reset();
|
483
|
+
return this;
|
484
|
+
}
|
485
|
+
|
486
|
+
@JRubyMethod()
|
487
|
+
public IRubyObject bubblebabble(ThreadContext context) {
|
488
|
+
final byte[] digest = algo.digest();
|
489
|
+
return RubyString.newString(context.runtime, BubbleBabble.bubblebabble(digest, 0, digest.length));
|
490
|
+
}
|
491
|
+
|
492
|
+
private void setAlgorithm(Metadata metadata) throws NoSuchAlgorithmException {
|
493
|
+
this.algo = createMessageDigest(metadata.getName());
|
494
|
+
this.blockLength = metadata.getBlockLength();
|
495
|
+
}
|
496
|
+
|
497
|
+
}
|
498
|
+
}// RubyDigest
|
@@ -0,0 +1,41 @@
|
|
1
|
+
/*
|
2
|
+
**** BEGIN LICENSE BLOCK *****
|
3
|
+
* BSD 2-Clause License
|
4
|
+
*
|
5
|
+
* Copyright (c) 2010, Charles Oliver Nutter <headius@headius.com>
|
6
|
+
* All rights reserved.
|
7
|
+
*
|
8
|
+
* Redistribution and use in source and binary forms, with or without
|
9
|
+
* modification, are permitted provided that the following conditions are met:
|
10
|
+
*
|
11
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
12
|
+
* list of conditions and the following disclaimer.
|
13
|
+
*
|
14
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
15
|
+
* this list of conditions and the following disclaimer in the documentation
|
16
|
+
* and/or other materials provided with the distribution.
|
17
|
+
*
|
18
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
***** END LICENSE BLOCK *****/
|
29
|
+
|
30
|
+
package org.jruby.ext.digest;
|
31
|
+
|
32
|
+
import java.io.IOException;
|
33
|
+
import org.jruby.Ruby;
|
34
|
+
import org.jruby.runtime.load.Library;
|
35
|
+
|
36
|
+
public class SHA1 implements Library {
|
37
|
+
|
38
|
+
public void load(final Ruby runtime, boolean wrap) throws IOException {
|
39
|
+
org.jruby.ext.digest.RubyDigest.createDigestSHA1(runtime);
|
40
|
+
}
|
41
|
+
}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
/*
|
2
|
+
**** BEGIN LICENSE BLOCK *****
|
3
|
+
* BSD 2-Clause License
|
4
|
+
*
|
5
|
+
* Copyright (c) 2010, Charles Oliver Nutter <headius@headius.com>
|
6
|
+
* All rights reserved.
|
7
|
+
*
|
8
|
+
* Redistribution and use in source and binary forms, with or without
|
9
|
+
* modification, are permitted provided that the following conditions are met:
|
10
|
+
*
|
11
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
12
|
+
* list of conditions and the following disclaimer.
|
13
|
+
*
|
14
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
15
|
+
* this list of conditions and the following disclaimer in the documentation
|
16
|
+
* and/or other materials provided with the distribution.
|
17
|
+
*
|
18
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
***** END LICENSE BLOCK *****/
|
29
|
+
|
30
|
+
package org.jruby.ext.digest;
|
31
|
+
|
32
|
+
import java.io.IOException;
|
33
|
+
import org.jruby.Ruby;
|
34
|
+
import org.jruby.runtime.load.Library;
|
35
|
+
|
36
|
+
public class SHA2 implements Library {
|
37
|
+
|
38
|
+
public void load(final Ruby runtime, boolean wrap) throws IOException {
|
39
|
+
org.jruby.ext.digest.RubyDigest.createDigestSHA2(runtime);
|
40
|
+
}
|
41
|
+
}
|
data/lib/digest/sha2.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#--
|
3
|
+
# sha2.rb - defines Digest::SHA2 class which wraps up the SHA256,
|
4
|
+
# SHA384, and SHA512 classes.
|
5
|
+
#++
|
6
|
+
# Copyright (c) 2006 Akinori MUSHA <knu@iDaemons.org>
|
7
|
+
#
|
8
|
+
# All rights reserved. You can redistribute and/or modify it under the same
|
9
|
+
# terms as Ruby.
|
10
|
+
#
|
11
|
+
# $Id$
|
12
|
+
|
13
|
+
require 'digest'
|
14
|
+
require 'digest/sha2/loader'
|
15
|
+
|
16
|
+
module Digest
|
17
|
+
#
|
18
|
+
# A meta digest provider class for SHA256, SHA384 and SHA512.
|
19
|
+
#
|
20
|
+
# FIPS 180-2 describes SHA2 family of digest algorithms. It defines
|
21
|
+
# three algorithms:
|
22
|
+
# * one which works on chunks of 512 bits and returns a 256-bit
|
23
|
+
# digest (SHA256),
|
24
|
+
# * one which works on chunks of 1024 bits and returns a 384-bit
|
25
|
+
# digest (SHA384),
|
26
|
+
# * and one which works on chunks of 1024 bits and returns a 512-bit
|
27
|
+
# digest (SHA512).
|
28
|
+
#
|
29
|
+
# ==Examples
|
30
|
+
# require 'digest'
|
31
|
+
#
|
32
|
+
# # Compute a complete digest
|
33
|
+
# Digest::SHA2.hexdigest 'abc' # => "ba7816bf8..."
|
34
|
+
# Digest::SHA2.new(256).hexdigest 'abc' # => "ba7816bf8..."
|
35
|
+
# Digest::SHA256.hexdigest 'abc' # => "ba7816bf8..."
|
36
|
+
#
|
37
|
+
# Digest::SHA2.new(384).hexdigest 'abc' # => "cb00753f4..."
|
38
|
+
# Digest::SHA384.hexdigest 'abc' # => "cb00753f4..."
|
39
|
+
#
|
40
|
+
# Digest::SHA2.new(512).hexdigest 'abc' # => "ddaf35a19..."
|
41
|
+
# Digest::SHA512.hexdigest 'abc' # => "ddaf35a19..."
|
42
|
+
#
|
43
|
+
# # Compute digest by chunks
|
44
|
+
# sha2 = Digest::SHA2.new # =>#<Digest::SHA2:256>
|
45
|
+
# sha2.update "ab"
|
46
|
+
# sha2 << "c" # alias for #update
|
47
|
+
# sha2.hexdigest # => "ba7816bf8..."
|
48
|
+
#
|
49
|
+
# # Use the same object to compute another digest
|
50
|
+
# sha2.reset
|
51
|
+
# sha2 << "message"
|
52
|
+
# sha2.hexdigest # => "ab530a13e..."
|
53
|
+
#
|
54
|
+
class SHA2 < Digest::Class
|
55
|
+
# call-seq:
|
56
|
+
# Digest::SHA2.new(bitlen = 256) -> digest_obj
|
57
|
+
#
|
58
|
+
# Create a new SHA2 hash object with a given bit length.
|
59
|
+
#
|
60
|
+
# Valid bit lengths are 256, 384 and 512.
|
61
|
+
def initialize(bitlen = 256)
|
62
|
+
case bitlen
|
63
|
+
when 256
|
64
|
+
@sha2 = Digest::SHA256.new
|
65
|
+
when 384
|
66
|
+
@sha2 = Digest::SHA384.new
|
67
|
+
when 512
|
68
|
+
@sha2 = Digest::SHA512.new
|
69
|
+
else
|
70
|
+
raise ArgumentError, "unsupported bit length: %s" % bitlen.inspect
|
71
|
+
end
|
72
|
+
@bitlen = bitlen
|
73
|
+
end
|
74
|
+
|
75
|
+
# call-seq:
|
76
|
+
# digest_obj.reset -> digest_obj
|
77
|
+
#
|
78
|
+
# Reset the digest to the initial state and return self.
|
79
|
+
def reset
|
80
|
+
@sha2.reset
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
# call-seq:
|
85
|
+
# digest_obj.update(string) -> digest_obj
|
86
|
+
# digest_obj << string -> digest_obj
|
87
|
+
#
|
88
|
+
# Update the digest using a given _string_ and return self.
|
89
|
+
def update(str)
|
90
|
+
@sha2.update(str)
|
91
|
+
self
|
92
|
+
end
|
93
|
+
alias << update
|
94
|
+
|
95
|
+
def finish # :nodoc:
|
96
|
+
@sha2.digest!
|
97
|
+
end
|
98
|
+
private :finish
|
99
|
+
|
100
|
+
|
101
|
+
# call-seq:
|
102
|
+
# digest_obj.block_length -> Integer
|
103
|
+
#
|
104
|
+
# Return the block length of the digest in bytes.
|
105
|
+
#
|
106
|
+
# Digest::SHA256.new.block_length * 8
|
107
|
+
# # => 512
|
108
|
+
# Digest::SHA384.new.block_length * 8
|
109
|
+
# # => 1024
|
110
|
+
# Digest::SHA512.new.block_length * 8
|
111
|
+
# # => 1024
|
112
|
+
def block_length
|
113
|
+
@sha2.block_length
|
114
|
+
end
|
115
|
+
|
116
|
+
# call-seq:
|
117
|
+
# digest_obj.digest_length -> Integer
|
118
|
+
#
|
119
|
+
# Return the length of the hash value (the digest) in bytes.
|
120
|
+
#
|
121
|
+
# Digest::SHA256.new.digest_length * 8
|
122
|
+
# # => 256
|
123
|
+
# Digest::SHA384.new.digest_length * 8
|
124
|
+
# # => 384
|
125
|
+
# Digest::SHA512.new.digest_length * 8
|
126
|
+
# # => 512
|
127
|
+
#
|
128
|
+
# For example, digests produced by Digest::SHA256 will always be 32 bytes
|
129
|
+
# (256 bits) in size.
|
130
|
+
def digest_length
|
131
|
+
@sha2.digest_length
|
132
|
+
end
|
133
|
+
|
134
|
+
def initialize_copy(other) # :nodoc:
|
135
|
+
@sha2 = other.instance_eval { @sha2.clone }
|
136
|
+
end
|
137
|
+
|
138
|
+
def inspect # :nodoc:
|
139
|
+
"#<%s:%d %s>" % [self.class.name, @bitlen, hexdigest]
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
data/lib/digest.jar
ADDED
Binary file
|
data/lib/digest.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
if defined?(Digest) &&
|
4
|
+
/\A(?:2\.|3\.0\.[0-2]\z)/.match?(RUBY_VERSION) &&
|
5
|
+
caller_locations.any? { |l|
|
6
|
+
%r{/(rubygems/gem_runner|bundler/cli)\.rb}.match?(l.path)
|
7
|
+
}
|
8
|
+
# Before Ruby 3.0.3/3.1.0, the gem and bundle commands used to load
|
9
|
+
# the digest library before loading additionally installed gems, so
|
10
|
+
# you will get constant redefinition warnings and unexpected
|
11
|
+
# implementation overwriting if we proceed here. Avoid that.
|
12
|
+
return
|
13
|
+
end
|
14
|
+
|
15
|
+
require 'digest/version'
|
16
|
+
require 'digest/loader'
|
17
|
+
|
18
|
+
module Digest
|
19
|
+
# A mutex for Digest().
|
20
|
+
REQUIRE_MUTEX = Thread::Mutex.new
|
21
|
+
|
22
|
+
def self.const_missing(name) # :nodoc:
|
23
|
+
case name
|
24
|
+
when :SHA256, :SHA384, :SHA512
|
25
|
+
lib = 'digest/sha2'
|
26
|
+
else
|
27
|
+
lib = File.join('digest', name.to_s.downcase)
|
28
|
+
end
|
29
|
+
|
30
|
+
begin
|
31
|
+
require lib
|
32
|
+
rescue LoadError
|
33
|
+
raise LoadError, "library not found for class Digest::#{name} -- #{lib}", caller(1)
|
34
|
+
end
|
35
|
+
unless Digest.const_defined?(name)
|
36
|
+
raise NameError, "uninitialized constant Digest::#{name}", caller(1)
|
37
|
+
end
|
38
|
+
Digest.const_get(name)
|
39
|
+
end
|
40
|
+
|
41
|
+
class ::Digest::Class
|
42
|
+
# Creates a digest object and reads a given file, _name_.
|
43
|
+
# Optional arguments are passed to the constructor of the digest
|
44
|
+
# class.
|
45
|
+
#
|
46
|
+
# p Digest::SHA256.file("X11R6.8.2-src.tar.bz2").hexdigest
|
47
|
+
# # => "f02e3c85572dc9ad7cb77c2a638e3be24cc1b5bea9fdbb0b0299c9668475c534"
|
48
|
+
def self.file(name, *args)
|
49
|
+
new(*args).file(name)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns the base64 encoded hash value of a given _string_. The
|
53
|
+
# return value is properly padded with '=' and contains no line
|
54
|
+
# feeds.
|
55
|
+
def self.base64digest(str, *args)
|
56
|
+
[digest(str, *args)].pack('m0')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module Instance
|
61
|
+
# Updates the digest with the contents of a given file _name_ and
|
62
|
+
# returns self.
|
63
|
+
def file(name)
|
64
|
+
File.open(name, "rb") {|f|
|
65
|
+
buf = ""
|
66
|
+
while f.read(16384, buf)
|
67
|
+
update buf
|
68
|
+
end
|
69
|
+
}
|
70
|
+
self
|
71
|
+
end
|
72
|
+
|
73
|
+
# If none is given, returns the resulting hash value of the digest
|
74
|
+
# in a base64 encoded form, keeping the digest's state.
|
75
|
+
#
|
76
|
+
# If a +string+ is given, returns the hash value for the given
|
77
|
+
# +string+ in a base64 encoded form, resetting the digest to the
|
78
|
+
# initial state before and after the process.
|
79
|
+
#
|
80
|
+
# In either case, the return value is properly padded with '=' and
|
81
|
+
# contains no line feeds.
|
82
|
+
def base64digest(str = nil)
|
83
|
+
[str ? digest(str) : digest].pack('m0')
|
84
|
+
end
|
85
|
+
|
86
|
+
# Returns the resulting hash value and resets the digest to the
|
87
|
+
# initial state.
|
88
|
+
def base64digest!
|
89
|
+
[digest!].pack('m0')
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# call-seq:
|
95
|
+
# Digest(name) -> digest_subclass
|
96
|
+
#
|
97
|
+
# Returns a Digest subclass by +name+ in a thread-safe manner even
|
98
|
+
# when on-demand loading is involved.
|
99
|
+
#
|
100
|
+
# require 'digest'
|
101
|
+
#
|
102
|
+
# Digest("MD5")
|
103
|
+
# # => Digest::MD5
|
104
|
+
#
|
105
|
+
# Digest(:SHA256)
|
106
|
+
# # => Digest::SHA256
|
107
|
+
#
|
108
|
+
# Digest(:Foo)
|
109
|
+
# # => LoadError: library not found for class Digest::Foo -- digest/foo
|
110
|
+
def Digest(name)
|
111
|
+
const = name.to_sym
|
112
|
+
Digest::REQUIRE_MUTEX.synchronize {
|
113
|
+
# Ignore autoload's because it is void when we have #const_missing
|
114
|
+
Digest.const_missing(const)
|
115
|
+
}
|
116
|
+
rescue LoadError
|
117
|
+
# Constants do not necessarily rely on digest/*.
|
118
|
+
if Digest.const_defined?(const)
|
119
|
+
Digest.const_get(const)
|
120
|
+
else
|
121
|
+
raise
|
122
|
+
end
|
123
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: digest
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 3.1.0
|
5
|
+
platform: java
|
6
|
+
authors:
|
7
|
+
- Akinori MUSHA
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-12-24 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Provides a framework for message digest libraries.
|
14
|
+
email:
|
15
|
+
- knu@idaemons.org
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- LICENSE.txt
|
21
|
+
- README.md
|
22
|
+
- ext/java/org/jruby/ext/digest/BubbleBabble.java
|
23
|
+
- ext/java/org/jruby/ext/digest/DigestLibrary.java
|
24
|
+
- ext/java/org/jruby/ext/digest/MD5.java
|
25
|
+
- ext/java/org/jruby/ext/digest/RMD160.java
|
26
|
+
- ext/java/org/jruby/ext/digest/RubyDigest.java
|
27
|
+
- ext/java/org/jruby/ext/digest/SHA1.java
|
28
|
+
- ext/java/org/jruby/ext/digest/SHA2.java
|
29
|
+
- ext/java/org/jruby/ext/digest/lib/digest/bubblebabble.rb
|
30
|
+
- ext/java/org/jruby/ext/digest/lib/digest/loader.rb
|
31
|
+
- ext/java/org/jruby/ext/digest/lib/digest/md5.rb
|
32
|
+
- ext/java/org/jruby/ext/digest/lib/digest/rmd160.rb
|
33
|
+
- ext/java/org/jruby/ext/digest/lib/digest/sha1.rb
|
34
|
+
- ext/java/org/jruby/ext/digest/lib/digest/sha2/loader.rb
|
35
|
+
- lib/digest.jar
|
36
|
+
- lib/digest.rb
|
37
|
+
- lib/digest/sha2.rb
|
38
|
+
- lib/digest/version.rb
|
39
|
+
homepage: https://github.com/ruby/digest
|
40
|
+
licenses:
|
41
|
+
- Ruby
|
42
|
+
- BSD-2-Clause
|
43
|
+
metadata:
|
44
|
+
msys2_mingw_dependencies: openssl
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
- ext/java/org/jruby/ext/digest/lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.5.0
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
requirements: []
|
61
|
+
rubygems_version: 3.2.14
|
62
|
+
signing_key:
|
63
|
+
specification_version: 4
|
64
|
+
summary: Provides a framework for message digest libraries.
|
65
|
+
test_files: []
|