在 JRuby 中使用 Java 的 MessageDigest class
Using Java's MessageDigest class with JRuby
我正在尝试使用 Java 的消息摘要 class 为我的 rails 应用程序中的大量文件计算 md5 哈希值。我用 JRuby 在 ruby 脚本中编写了一些代码,但是对 Files.readAllBytes() 的调用给了我 "undefined method `getFileSystem' for #"。这是我在 ruby:
中写的方法
def calculate_md5_java(zip)
require 'java'
import java.security.MessageDigest
import java.nio.file.Files
import javax.xml.bind.DatatypeConverter
import java.nio.file.FileSystems
md = MessageDigest.getInstance("MD5")
FileUtils.cp(zip, "GODPLEASELETTHISWORK.zip")
Zip::File.open("GODPLEASELETTHISWORK.zip") do |z|
z.each do |entry|
md.update(Files.readAllBytes(entry.get_input_stream))
end
end
digest = md.digest()
DatatypeConverter.printHexBinary(digest).toLowerCase()
end
我也试过将我的论点改为
md.update(entry.get_input_stream.read.bytes.to_a)
这给了我:
no method 'update' for arguments (org.jruby.RubyArray) on Java::JavaSecurity::MessageDigest::Delegate available overloads: (byte) (java.nio.ByteBuffer) (byte[])
哦土豆!看起来有点复杂……这样可以接受吗?
def check_please(file)
checksums = {}
Zlib::GzipReader.wrap(file) do |gz|
Gem::Package::TarReader.new(gz) do |tar|
tar.each do |entry|
checksums[entry.full_name] = Digest::MD5.hexdigest(entry.read) if entry.file?
end
end
end
checksums
end
File.open("foo.tgz", "rb") do |file|
puts check_please(file)
end
为了它的价值,我正在使用这个版本的 JRuby 和 Java。
jruby 9.1.9.0 (2.3.3) 2017-05-15 28aa830 Java HotSpot(TM) 64-Bit Server VM 25.40-b25 on 1.8.0_40-b27 +jit [darwin-x86_64]
另外,在到期的地方记分:http://weblog.jamisbuck.org/2015/7/23/tar-gz-in-ruby.html
我根据传递到此处的文件创建了一个 java 文件对象,然后将 File.toPath 传递到 readAllBytes。 readAllBytes 不需要字符串路径,而是 Path 对象。
def calculate_md5_java(xmls)
require 'java'
import java.security.MessageDigest
import java.nio.file.Files
import javax.xml.bind.DatatypeConverter
import java.nio.file.FileSystems
import java.io.ByteArrayOutputStream
import java.io.DataOutputStream
md = MessageDigest.getInstance("MD5")
baos = ByteArrayOutputStream.new
out = DataOutputStream.new(baos)
xmls = Hash[xmls.sort_by { |k,v| k.tr(':', '-').to_s }]
xmls.values.each do |xml|
xml_file = java.io.File.new(xml.path)
md.update(Files.readAllBytes(xml_file.toPath()))
end
digest = md.digest()
md5 = DatatypeConverter.printHexBinary(digest)
md5.downcase!
end
我正在尝试使用 Java 的消息摘要 class 为我的 rails 应用程序中的大量文件计算 md5 哈希值。我用 JRuby 在 ruby 脚本中编写了一些代码,但是对 Files.readAllBytes() 的调用给了我 "undefined method `getFileSystem' for #"。这是我在 ruby:
中写的方法def calculate_md5_java(zip)
require 'java'
import java.security.MessageDigest
import java.nio.file.Files
import javax.xml.bind.DatatypeConverter
import java.nio.file.FileSystems
md = MessageDigest.getInstance("MD5")
FileUtils.cp(zip, "GODPLEASELETTHISWORK.zip")
Zip::File.open("GODPLEASELETTHISWORK.zip") do |z|
z.each do |entry|
md.update(Files.readAllBytes(entry.get_input_stream))
end
end
digest = md.digest()
DatatypeConverter.printHexBinary(digest).toLowerCase()
end
我也试过将我的论点改为
md.update(entry.get_input_stream.read.bytes.to_a)
这给了我:
no method 'update' for arguments (org.jruby.RubyArray) on Java::JavaSecurity::MessageDigest::Delegate available overloads: (byte) (java.nio.ByteBuffer) (byte[])
哦土豆!看起来有点复杂……这样可以接受吗?
def check_please(file)
checksums = {}
Zlib::GzipReader.wrap(file) do |gz|
Gem::Package::TarReader.new(gz) do |tar|
tar.each do |entry|
checksums[entry.full_name] = Digest::MD5.hexdigest(entry.read) if entry.file?
end
end
end
checksums
end
File.open("foo.tgz", "rb") do |file|
puts check_please(file)
end
为了它的价值,我正在使用这个版本的 JRuby 和 Java。
jruby 9.1.9.0 (2.3.3) 2017-05-15 28aa830 Java HotSpot(TM) 64-Bit Server VM 25.40-b25 on 1.8.0_40-b27 +jit [darwin-x86_64]
另外,在到期的地方记分:http://weblog.jamisbuck.org/2015/7/23/tar-gz-in-ruby.html
我根据传递到此处的文件创建了一个 java 文件对象,然后将 File.toPath 传递到 readAllBytes。 readAllBytes 不需要字符串路径,而是 Path 对象。
def calculate_md5_java(xmls)
require 'java'
import java.security.MessageDigest
import java.nio.file.Files
import javax.xml.bind.DatatypeConverter
import java.nio.file.FileSystems
import java.io.ByteArrayOutputStream
import java.io.DataOutputStream
md = MessageDigest.getInstance("MD5")
baos = ByteArrayOutputStream.new
out = DataOutputStream.new(baos)
xmls = Hash[xmls.sort_by { |k,v| k.tr(':', '-').to_s }]
xmls.values.each do |xml|
xml_file = java.io.File.new(xml.path)
md.update(Files.readAllBytes(xml_file.toPath()))
end
digest = md.digest()
md5 = DatatypeConverter.printHexBinary(digest)
md5.downcase!
end