В моем коде мне нужно хэшировать файлы, используя различные алгоритмы, включая CRC32.Поскольку я также использую другие криптографические хеш-функции в семействе Digest
, я подумал, что было бы неплохо поддерживать согласованный интерфейс для них всех.
Для записи я нашел digest-crc
, драгоценный камень, который делает именно то, что я хочу.Дело в том, что Zlib
является частью стандартной библиотеки и имеет рабочую реализацию CRC32, которую я хотел бы использовать повторно.Кроме того, он написан на C, поэтому должен обеспечивать превосходную производительность по отношению к digest-crc
, который является чисто рубиновой реализацией.
Реализация 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(digest)
, , который работает со значениемДайджест на уровне байтов .Я не уверен, как эта функция работает, поэтому мне было интересно, возможно ли достичь этого только с помощью целого числа, возвращенного из Zlib.crc32
.