【问题标题】:Using Java's MessageDigest class with JRuby在 JRuby 中使用 Java 的 MessageDigest 类
【发布时间】:2018-07-17 03:22:16
【问题描述】:

我正在尝试使用 Java 的消息摘要类来计算我的 rails 应用程序内部大量文件的 md5 哈希值。我已经用 JRuby 在 ruby​​ 脚本中编写了一些代码,但是对 Files.readAllBytes() 的调用给了我“未定义的方法 `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[])

【问题讨论】:

  • 喂!您使用的是什么版本的 Java 和 JRuby?

标签: ruby-on-rails ruby jruby


【解决方案1】:

哦,土豆!看起来有点复杂……这可以接受吗?

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

【讨论】:

    【解决方案2】:

    我根据传入的文件创建了一个 java File 对象,然后将 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-07
      • 1970-01-01
      • 2018-10-13
      • 1970-01-01
      • 1970-01-01
      • 2022-11-06
      • 2011-03-10
      相关资源
      最近更新 更多