首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Digest::CRC32 with Zlib

Digest::CRC32 with Zlib
EN

Stack Overflow用户
提问于 2011-12-22 02:40:10
回答 3查看 4.7K关注 0票数 7

在我的代码中,我需要使用各种算法来散列文件,包括CRC32。由于我还在使用Digest家族中的其他加密哈希函数,因此我认为为所有这些函数维护一个一致的接口会很好。

顺便说一句,我确实找到了digest-crc,这是一个能做我想做的事情的宝石。问题是,Zlib是标准库的一部分,并且有一个我想要重用的CRC32的工作实现。此外,它是用C语言编写的,因此它应该比纯ruby实现的digest-crc提供更好的性能。

一开始,实现Digest::CRC32实际上看起来非常简单:

代码语言:javascript
复制
%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

一切看起来都很正常:

代码语言:javascript
复制
crc32 = File.open('Rakefile') { |f| Zlib.crc32 f.read }
digest = Digest::CRC32.file('Rakefile').digest!.to_i
crc32 == digest
=> true

不幸的是,并不是所有的东西都能正常工作:

代码语言:javascript
复制
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)which works with the value of the digest at the byte level。我不确定该函数是如何工作的,所以我想知道是否可以仅使用从Zlib.crc32返回的整数来实现这一点。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-12-22 10:49:21

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

你想要像这样的东西

代码语言:javascript
复制
[@crc32].pack('V')

将该整数转换为表示该整数的字节。一定要去阅读pack和它的各种格式说明符--有很多方法可以打包一个整数,这取决于字节是否应该以本机endian-ness、big-endian、little-endian等表示,所以您应该找出哪种方法符合您的需要

票数 6
EN

Stack Overflow用户

发布于 2011-12-22 07:01:35

抱歉,这并没有真正回答你的问题,但它可能会有所帮助..

首先,在读取文件时,请确保传递"rb“参数。我知道你不在windows上,但是如果你的代码碰巧在windows机器上运行,你的代码就不能正常工作了,尤其是在读取ruby文件的时候。示例:

代码语言:javascript
复制
crc32 = File.open('test.rb') { |f| Zlib.crc32 f.read }
#=> 189072290
digest = Digest::CRC32.file('test.rb').digest!.to_i
#=> 314435800
crc32 == digest
#=> false

crc32 = File.open('test.rb', "rb") { |f| Zlib.crc32 f.read }
#=> 314435800
digest = Digest::CRC32.file('test.rb').digest!.to_i
#=> 314435800
crc32 == digest
#=> true

上面的代码将适用于所有平台和所有红宝石..据我所知..但这不是你想要的..

我非常确定上面例子中的hexdigest和digest方法是正常工作的。

代码语言:javascript
复制
dig_file = Digest::CRC32.file('test.rb')

test1 = dig_file.hexdigest
#=> "333134343335383030"

test2 = dig_file.digest
#=> "314435800"

def hexdigest_to_digest(h)
  h.unpack('a2'*(h.size/2)).collect {|i| i.hex.chr }.join
end

test3 = hexdigest_to_digest(test1)
#=> "314435800"

所以我猜要么是.to_i.to_s(16)抛出了你的预期结果,要么你的预期结果可能是错的?不确定,但万事如意

票数 3
EN

Stack Overflow用户

发布于 2014-10-04 06:22:24

它工作得很好,确保始终使用网络字节顺序,如下所示:

代码语言:javascript
复制
def finish; [@crc32].pack('N'); end
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8594702

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档