Skip to content

Instantly share code, notes, and snippets.

@ajesler
Last active July 5, 2024 07:15
Show Gist options
  • Save ajesler/96273487209913ddb40c242b05af23d1 to your computer and use it in GitHub Desktop.
Save ajesler/96273487209913ddb40c242b05af23d1 to your computer and use it in GitHub Desktop.
# Caculate the BSCCO checksum for a file
# Usage: `$ ruby bscco.rb your_file.txt`
# Based on the algorithm description in https://www.elexon.co.uk/wp-content/uploads/2013/11/bscp533_appx_a_v17.0.pdf
def bscco(file)
lines_except_last = File.read(file).lines[0..-2]
lines_as_bytes = lines_except_last
.map(&:chomp)
.map(&:bytes)
.map do |line_bytes|
unless (remainder = line_bytes.length % 4) == 0
# pad with 0s so it is a multiple of 4
line_bytes += [0] * (4 - remainder)
end
line_bytes
end
file_contents = lines_as_bytes.flatten.to_a
num_chars = file_contents.length
checksum = file_contents.each_slice(4).inject(0) do |chk, cur_bytes|
current_word = cur_bytes.inject(0) { |initial, cur_byte| (initial << 8) + cur_byte }
chk ^ current_word
end
checksum
end
file_path = ARGV.shift
checksum = bscco(file_path)
puts "#{file_path} #{checksum}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment