摘要:: CRC32与Zlib

Mat*_*ira 6 ruby digest

在我的代码中,我需要使用各种算法来散列文件,包括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
Run Code Online (Sandbox Code Playgroud)

一切看起来都正确:

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

不幸的是,并非一切正常:

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

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

hexdigest基本上返回Digest.hexencode(digest),它与字节级别的摘要值一起使用.我不确定该函数是如何工作的,所以我想知道是否可以通过返回的整数实现这一点Zlib.crc32.

Fre*_*ung 6

Digest期望摘要返回组成校验和的原始字节,即在crc32的情况下,构成32位整数的4个字节.但是,您将返回一个包含该整数的基数10表示的字符串.

你想要的东西

[@crc32].pack('V')
Run Code Online (Sandbox Code Playgroud)

将该整数转换为表示该整数的字节.请继续阅读pack及其各种格式说明符 - 有很多方法可以打包整数,具体取决于字节是否应该以本机字节序,big-endian,little-endian等表示,所以你应该弄清楚哪个一个符合您的需求