在我的代码中,我需要使用各种算法来散列文件,包括CRC32。由于我还在使用Digest家族中的其他加密哈希函数,因此我认为为所有这些函数维护一个一致的接口会很好。
顺便说一句,我确实找到了digest-crc,这是一个能做我想做的事情的宝石。问题是,Zlib是标准库的一部分,并且有一个我想要重用的CRC32的工作实现。此外,它是用C语言编写的,因此它应该比纯ruby实现的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),which works with the value of the digest at the byte level。我不确定该函数是如何工作的,所以我想知道是否可以仅使用从Zlib.crc32返回的整数来实现这一点。
发布于 2011-12-22 10:49:21
摘要期望摘要返回组成校验和的原始字节,即在crc32的情况下,返回组成32位整数的4个字节。但是,您将返回一个包含该整数的基数为10的表示形式的字符串。
你想要像这样的东西
[@crc32].pack('V')将该整数转换为表示该整数的字节。一定要去阅读pack和它的各种格式说明符--有很多方法可以打包一个整数,这取决于字节是否应该以本机endian-ness、big-endian、little-endian等表示,所以您应该找出哪种方法符合您的需要
发布于 2011-12-22 07:01:35
抱歉,这并没有真正回答你的问题,但它可能会有所帮助..
首先,在读取文件时,请确保传递"rb“参数。我知道你不在windows上,但是如果你的代码碰巧在windows机器上运行,你的代码就不能正常工作了,尤其是在读取ruby文件的时候。示例:
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方法是正常工作的。
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)抛出了你的预期结果,要么你的预期结果可能是错的?不确定,但万事如意
发布于 2014-10-04 06:22:24
它工作得很好,确保始终使用网络字节顺序,如下所示:
def finish; [@crc32].pack('N'); endhttps://stackoverflow.com/questions/8594702
复制相似问题