Дайджест :: CRC32 с Zlib

В моем коде мне нужно хэшировать файлы, используя различные алгоритмы, включая CRC32. Поскольку я также использую другие криптографические хеш-функции из семейства Digest , я подумал, что было бы неплохо сохранить согласованный интерфейс для всех них.

Для протокола, я нашел digest-crc , драгоценный камень, который делает именно то, что я хочу. Дело в том, что Zlib является частью стандартной библиотеки и имеет рабочую реализацию CRC32, которую я бы хотел использовать повторно. Кроме того, он написан на C, поэтому должен обеспечивать лучшую производительность по сравнению с digest-crc , который является реализацией на чистом Ruby.

Реализация Digest :: CRC32 сначала выглядела довольно просто:

%w(digest zlib).each { |f| require f }

class Digest::CRC32 < Digest::Class
  include Digest::Instance

  def update(str)
    @crc32 = Zlib.crc32(str, @crc32)
  end

  def initialize; reset; end
  def reset; @crc32 = 0; end
  def finish; @crc32.to_s; end
end

Все выглядит правильно:

crc32 = File.open('Rakefile') { |f| Zlib.crc32 f.read }
digest = Digest::CRC32.file('Rakefile').digest!.to_i
crc32 == digest
=> true

К сожалению, не все работает:

Digest::CRC32.file('Rakefile').hexdigest!
=> "313635393830353832"

# What I actually expected was:
Digest::CRC32.file('Rakefile').digest!.to_i.to_s(16)
=> "9e4a9a6"

hexdigest в основном возвращает Digest .hexencode (дайджест) , , который работает со значением дайджеста на уровне байтов . Я не уверен, как работает эта функция, поэтому мне было интересно, можно ли добиться этого, используя только целое число, возвращенное из Zlib.crc32 .

6
задан Matheus Moreira 21 December 2011 в 18:40
поделиться