Использование Java-класса MessageDigest с JRuby - PullRequest
0 голосов
/ 28 июня 2018

Я пытаюсь использовать класс дайджеста сообщений Java для вычисления хеша md5 для большого количества файлов внутри моего приложения rails. Я написал некоторый код в сценарии ruby ​​с JRuby, но вызов Files.readAllBytes () дает мне «неопределенный метод getFileSystem для #». Вот метод, который я написал в 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[])

Ответы [ 2 ]

0 голосов
/ 16 июля 2018

Я создал объект File 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
0 голосов
/ 29 июня 2018

О, картошка! Это выглядит немного сложнее ... это приемлемо?

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

...