Question

As a programming assignment in a Cryptography course I have the following problem:

Read a video file, divide it in 1KB blocks, grab the last block, get it's SHA256 sum, append that sum to the second to last block, get the SHA256 sum of the resulting block, and so on and so forth... The answer to the problem is the last SHA256 sum you get from this chain. The answer yielded by this algorithm applied to a certain video is this SHA256 sum: '5b96aece304a1422224f9a41b228416028f9ba26b0d1058f400200f06a589949'.

I understand the problem, but I cannot solve it using Ruby.

This is my Ruby code:

require 'digest/sha2'

def chunker
  video, array = File.new('video.mp4', 'r'), []
  (0..video.size/1024).each { |i| array[i] = video.read 1024 }
  array
end

video_chunks, sha, digest = chunker, '', Digest::SHA2.new

video_chunks.reverse_each { |chunk| sha = (digest << chunk+sha).to_s }

puts sha

I'm basically dividing the video into 1024 byte chunks, then traversing it in reverse, getting the SHA256 sum of (currentBlock + lastSha) and saving it to a variable, which I output at the end of this reverse traversal.

This does not work.

The SHA256 sum of the first chunk (which doesn't have any past sha appended to it) is 'f2e208617302c6b089f52b6f27f78a7171b4424c1191989bbf86ed5ab0cbccee', I know this from a Java program which does the exact same problem. That sum is correct. But the second SHA256 sum, which is the SHA265 result of the appending of 'f2e2...' to the second to last block should be '34b6...' and it is outputting another thing. The problem occurs in the code "digest << chunk+sha". Somehow, when appending, something happens and the resulting sha is incorrect. Any ideas? :(

Was it helpful?

Solution

The sha should not be generated via .to_s, you need the binary string version. In addition you are feeding more and more blocks into the same digest, whilst your exercise is specifically about a process for doing the same thing but under your own control (i.e. in your own code).

So instead of maintaining a digest object, and calling .to_s on it to fetch each sub-hash, you should calculate the hash fresh each time using the Digest::SHA2.digest( data ) class method

Try this instead:

video_chunks, sha = chunker, ''

video_chunks.reverse_each { |chunk| sha = Digest::SHA2.digest( chunk+sha ) }

# Convert to hex:
puts sha.unpack('H*').first
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top