[Python] replicating "sha256 -C checksum_file.txt file.txt"

Hello everyone,

Since my python knowledge is limimted, I've challenged myself to learn as much as possible to help me with my carrere. I'm currently trying to convert a shell script to python, just to give myself a task. There is one section of the script that I'm having issues converting and that is this line:

sha256 -C SHA256 image.iso

which basically checks the checksum of "image.iso" against a textfile called SHA256, which contains the correct checksum.
A sample of "SHA256" is below (ignore the same checksum everywhere, it's just for example purposes):

SHA256 (that.iso) = 81833b79e23dc0f961ac5fb34484bca66386deb3181ddb8236870fa4f488cdd2
SHA256 (this.iso) = 81833b79e23dc0f961ac5fb34484bca66386deb3181ddb8236870fa4f488cdd2
SHA256 (image.iso) = 81833b79e23dc0f961ac5fb34484bca66386deb3181ddb8236870fa4f488cdd2

So far, I'm down to this python script:

import hashlib

workdir = '/tmp'
iso_image = 'image.iso'

def check_sha256(block_size=65536):
    sha256 = hashlib.sha256()
    with open(workdir + "/" + iso_name, 'rb') as f:
      for block in iter(lambda: f.read(block_size), b''):
        sha256.update(block)
    computed_sum = print(sha256.hexdigest())
    sha256sum 

but I'm stuck as to how I should go about picking up the correct line from the "SHA256" file and then compare the hash (I guess I can do it with "if variable in" or something.

Please guide me a bit here :slight_smile:

  1. Read the file "SHA256" line by line in a loop. (for line in filehandle)

  2. Tokenise each line as you read - the result will be stored in a list (hint: split after you strip)

  3. The last item of this list will be the hash value. Compare accordingly (hint: list_name[-1])

2 Likes

This is what I came up with so far, thank you for the hints:

workdir='/tmp'
iso_name='install65.iso'
sha_file='SHA256'

    file = open(workdir + '/' + sha_file, 'r')
    for lines in file:
        values = [x.strip('()') for x in lines.split()]
        #print(values)
        if iso_name == values[1]:
            print('file found')
            if computed_sum == values[-1]:
                print('hash OK')
                print(values[-1])
            else:
                print('hash NOT OK')
                print(values[-1])
                exit(1)
        else:
            print('file NOT found')
    file.close()

But I'm having a hard time understanding how I can search for one string (ex. iso name) and if found, use the same line and check for another string (hash sum).

The result of the code above is this;

38d1f8cadd502f1c27bf05c5abde6cc505dd28f3f34f8a941048ff9a54f9f608
file NOT found
file NOT found
file NOT found
file NOT found
file NOT found
file NOT found
file NOT found
file NOT found
file NOT found
file NOT found
file NOT found
file NOT found
file NOT found
file NOT found
file NOT found
file found
hash OK
38d1f8cadd502f1c27bf05c5abde6cc505dd28f3f34f8a941048ff9a54f9f608
file NOT found
file NOT found
file NOT found
file NOT found
file NOT found
file NOT found
file NOT found

--- Post updated at 12:02 PM ---

I spoke too soon.

I came up with this:

def check_sha256(block_size=65536):
#    fetch_sha256()
    sha256 = hashlib.sha256()
    with open(workdir + "/" + iso_name, 'rb') as f:
      for block in iter(lambda: f.read(block_size), b''):
        sha256.update(block)
    computed_sum = sha256.hexdigest()
    file = open(workdir + '/' + sha_file, 'r')
    for lines in file:
        values = [x.strip('()') for x in lines.split()]
        if iso_name in values[1]:
            if computed_sum in values[-1]:
                print('SHA256: OK')
                break
            else:
                print('SHA256: NOT OK. Exiting... ')
                exit(1)
    file.close()

It works fine from what I can see but any pointers on improvements would be welcomed!

Thank you very much!