在Ubuntu中生成文件哈希值的方法有几种,包含命令行和Python的hashlib接口调用。命令行生成文件哈希值有两种方式:
1)md5sum / shasum / sha1sum / sha224sum / sha256sum / sha384sum / sha512sum等命令
2)openssl命令,支持的哈希值生成方法包含:
Message Digest commands (see the `dgst’ command for more details)
blake2b512 blake2s256 md4 md5
rmd160 sha1 sha224 sha256
sha3-224 sha3-256 sha3-384 sha3-512
sha384 sha512 sha512-224 sha512-256
shake128 shake256 sm3
而hashlib接口调用在另一文中有简要描述。这里实现的方法是通过调用系统命令openssl实现的,即openssl md5 filename的实现格式。
用法:python3 genhash.py -ffilename -mmd5 或者 python3 genhash.py --file filename --method md5。测试操作系统为Ubuntu24.04。
genhash.py
'''
File: genhash.py
Author: Nega
Created: 12/02/24 Mon.
Updated: 12/03/24 Tue.
'''
#!/bin/python3
import optparse
import os
import sys
# 声明支持的哈希方法,OpenSSL支持不仅包含以下声明的方法,以下声明仅为演示
SUPPORTED_HASH_METHODS = ('md2/md4/md5/sha1/sha224/sha256/sha384/sha512/sha3-224/sha3-256/sha3-384/sha3-512/blake2s256/blake2b512/',)
def __generate_hash__(file_name, gen_method='md5', debug=False):
if gen_method is None or type(gen_method) != type('') or (gen_method + '/') not in SUPPORTED_HASH_METHODS[0]:
print('[\033[1;31mFAIL\033[0;39m] ' + str(gen_method) + ' not string or not supported')
return
if file_name is None or type(file_name) != type('') or file_name.strip() == '':
print('[\033[1;31mFAIL\033[0;39m] ' + str(file_name) + ' not string or invalid name')
return
if not os.path.exists(file_name) or not os.path.isfile(file_name):
print('[\033[1;31mFAIL\033[0;39m] ' + file_name + ' \033[1;31mnot existed\033[0;39m file')
return
res = os.popen('openssl ' + gen_method + ' ' + file_name)
digest_raw = res.read()
if debug is True:
print(digest_raw)
digest_str = digest_raw.split('=')[1].strip()
print('[' + gen_method.upper() + '] ' + digest_str)
temp = file_name
root_dir = None
if temp.startswith('~'):
temp = temp.replace('~', '/home/' + os.popen('whoami').read().replace('\n', ''))
root_dir = temp
elif temp.startswith('./'):
temp = os.getcwd() + temp[1:]
root_dir = temp
else:
root_dir = os.path.abspath(temp)
if root_dir is None:
print('[ERR] root directory not existed')
return
# print('[SOURCE]' + root_dir)
dig_file = '.' + gen_method
hash_dir = '__hash_cache__'
file_dir = root_dir[:root_dir.rindex('/')] + '/' + hash_dir
sim_file_name = root_dir[root_dir.rindex('/'):]
if not os.path.exists(file_dir) or not os.path.isdir(file_dir):
os.makedirs(file_dir)
file = file_dir + sim_file_name + dig_file
# print('[DEST] ' + file)
if os.path.exists(file) and os.path.isfile(file):
print('[\033[1;33mOVERRIDE\033[0;39m] digest file existed, rewriting..')
res2 = os.popen('chmod +w ' + file)
rstr = res2.read()
if rstr != '':
print('[FAIL] not writable')
return
with open(file, 'w') as f:
f.write(digest_str)
f.flush()
f.close()
if os.path.exists(file):
res2 = os.popen('chmod 664 ' + file)
rstr = res2.read()
if rstr == '': print('[\033[1;32mPASS\033[0;39m] TEST')
res3 = os.popen('ls -al | grep ' + file_name)
rstr2 = res3.read()
if rstr2.strip() != '': print(rstr2.replace('\n', ''))
else:
print('\033[1;31m[TEST]\033[0;39m Digest file generation failed')
def __pre_generate__(args=None):
if args is None or type(args) != type([]):
print('[TEST] Aborted with invalid arguments')
return
_parser = optparse.OptionParser()
_parser.add_option('-f', '--file',
type='string',
dest='gen_file',
default=None,
help='Choose a file to generate it\'s hash')
_parser.add_option('-m', '--method',
type='string',
dest='hash_method',
default=None,
help='Specify a hash method, such as md2/md3/md4/md5/sha1/sha224/sha256/sha384/sha512/blake2s256/blake2b512')
(_options, _) = _parser.parse_args(args)
gen_file = None
if _options.gen_file:
gen_file = _options.gen_file
gen_method = None
if _options.hash_method:
gen_method = _options.hash_method.lower()
__generate_hash__(gen_file, gen_method, False)
if __name__ == '__main__':
try:
__pre_generate__(sys.argv)
except Exception as err:
print('\033[1;31mERR.\033[0,39m ' + str(err))


8850

被折叠的 条评论
为什么被折叠?



