title: Digest::CRC32 with Zlib
body: <p>In my code, I need to hash files using a variety of algorithms, including CRC32. Since I'm also using other cryptographic hash functions in the <code>Digest</code> family, I thought it would be nice to maintain a consistent interface for them all.</p>
  
  <p>For the record, I did find <a href="https://github.com/postmodern/digest-crc" rel="noreferrer"><code>digest-crc</code></a>, a gem which does exactly what I want. The thing is, <code>Zlib</code> is part of the standard library and has a working implementation of CRC32 that I'd like to reuse. Also, it is written in C so it should offer superior performance in relation to <code>digest-crc</code>, which is a pure-ruby implementation.</p>
  
  <p>Implementing <code>Digest::CRC32</code> actually looked pretty straightforward at first:</p>
  
  <pre><code>%w(digest zlib).each { |f| require f }
  
  class Digest::CRC32 &lt; 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
  </code></pre>
  
  <p>Everything looks right:</p>
  
  <pre><code>crc32 = File.open('Rakefile') { |f| Zlib.crc32 f.read }
  digest = Digest::CRC32.file('Rakefile').digest!.to_i
  crc32 == digest
  =&gt; true
  </code></pre>
  
  <p>Unfortunately, not everything works:</p>
  
  <pre><code>Digest::CRC32.file('Rakefile').hexdigest!
  =&gt; "313635393830353832"
  
  # What I actually expected was:
  Digest::CRC32.file('Rakefile').digest!.to_i.to_s(16)
  =&gt; "9e4a9a6"
  </code></pre>
  
  <p><code>hexdigest</code> basically returns <code>Digest.hexencode(digest)</code>, <a href="https://github.com/ruby/ruby/blob/trunk/ext/digest/digest.c#L81" rel="noreferrer">which works with the value of the digest at the byte level</a>. I'm not sure how that function works, so I was wondering if it is possible to achieve this with just the integer returned from <code>Zlib.crc32</code>.</p>