On Day 14 we have MD5 hashing again. I don’t wont to explain this one in different words. I will just post my solutions
require "digest"
salt = "abc"
index = 0
fives = []
hashes = []
while true
hash = Digest::MD5.hexdigest([salt, index].join)
if hash =~ /(.)\1{4}/
valid = fives.select { |five| five[0] == Regexp.last_match[1] && index <= five[1] }
valid.each do |v|
fives.delete(v)
hashes.push([*v, hash, index])
end
end
if hash =~ /(.)\1{2}/
fives.push([Regexp.last_match[1], index + 1000, hash])
end
if hashes.size == 64
break
end
index += 1
end
hashes.sort { |a, b| a[1] <=> b[1] }.each { |h| puts "#{h[2]} at #{h[1] - 1000}, matching five hash at #{h[3]} value = #{h[4]}" }
And here is solution for second part:
require "digest"
salt = "abc"
index = 0
def md5(salt, index)
hash = Digest::MD5.hexdigest([salt, index].join)
2016.times { hash = Digest::MD5.hexdigest(hash) }
hash
end
triplets = []
hashes = []
max_index = nil
while true
hash = md5(salt, index)
if hash =~ /(.)\1{4}/
triplets.select! { |triplet| (index - triplet[:index]) <= 1000 }
triplets.each do |triplet|
if triplet[:char] == Regexp.last_match[1] &&
hashes.push(triplet)
end
end
end
if hash =~ /(.)\1{2}/ && !max_index
triplets.push({ char: Regexp.last_match[1], index: index })
end
if hashes.size >= 64
max_index = index
if triplets.empty?
break
end
end
index += 1
if index % 100 == 0
puts [index, hashes.size].inspect
end
end
puts hashes.sort { |a, b| a[:index] <=> b[:index] }[63].inspect