aboutsummaryrefslogtreecommitdiffstats
path: root/fhash
diff options
context:
space:
mode:
authormjfernez <mjfernez@gmail.com>2021-03-29 20:19:25 -0400
committermjfernez <mjfernez@gmail.com>2021-03-29 20:19:25 -0400
commit242c3b75cffbffae114dd4a2b7dc453399cfa428 (patch)
tree9110b317ee65c688916628a5831dd430e27a7e56 /fhash
parentb45b3948e5082a1b20419286a5059bd93834d167 (diff)
downloadscripts-n-tools-242c3b75cffbffae114dd4a2b7dc453399cfa428.tar.gz
Fhash clean up and unit tests
Added saner unit testing in the tests folder, which can be added to by expanding the data in the tests/hashes.json file. Also removed some redundant comments and inconsistencies
Diffstat (limited to 'fhash')
-rwxr-xr-xfhash/fhash.py29
-rw-r--r--fhash/tests/TESTING (renamed from fhash/tests/shattered/TESTING)7
-rw-r--r--fhash/tests/basic/TESTING4
-rw-r--r--fhash/tests/files/shattered-1.pdf (renamed from fhash/tests/shattered/shattered-1.pdf)bin422435 -> 422435 bytes
-rw-r--r--fhash/tests/files/shattered-2.pdf (renamed from fhash/tests/shattered/shattered-2.pdf)bin422435 -> 422435 bytes
-rw-r--r--fhash/tests/files/smolgrownup.png (renamed from fhash/tests/basic/smolgrownup.png)bin1984243 -> 1984243 bytes
-rw-r--r--fhash/tests/files/textfile (renamed from fhash/tests/basic/textfile)0
-rw-r--r--fhash/tests/hashes.json50
-rw-r--r--fhash/tests/run_tests.py62
9 files changed, 130 insertions, 22 deletions
diff --git a/fhash/fhash.py b/fhash/fhash.py
index 4576873..bbed200 100755
--- a/fhash/fhash.py
+++ b/fhash/fhash.py
@@ -1,29 +1,22 @@
#!/usr/bin/python3
"""
fhash is a simple python tool for generating, passing and formatting hash
-values. It can be used to print hashes of strings or files in various formats
+values. It can be used to print hashes of strings or files in various FORMATS
including as a hex string (lower and uppercase), binary string, or decimal
number. It can also be used for testing the speed of these various functions
"""
-# OS/filesystem
import os
import sys
import locale
-
-# Hash functions
import hashlib
-
-# CLI tool
import argparse
-
-#IO and time
import time
# Defines the basic options and constants used
-algos = ['md5', 'sha1', 'sha2', 'sha3']
-modes = [224, 256, 384, 512]
-formats = ['lowercase', 'uppercase', 'binary', 'decimal']
+ALGOS = ['md5', 'sha1', 'sha2', 'sha3']
+SIZES = [224, 256, 384, 512]
+FORMATS = ['lowercase', 'uppercase', 'binary', 'decimal']
os_encoding = locale.getpreferredencoding()
# For sha256 and sha3 only
@@ -47,8 +40,8 @@ def check_function(func, size):
@size: the desired length of the output. i.e. sha256
outputs a message of 256 bits or 64 hex-digits
"""
- if (func in algos[0:2]):
- bsize = 160 if (algos.index(func)) else 128
+ if (func in ALGOS[0:2]):
+ bsize = 160 if (ALGOS.index(func)) else 128
if (size == None):
v_print('Using default message size of \
{} bits'.format(bsize))
@@ -61,7 +54,7 @@ def check_function(func, size):
if (size == None):
v_print('Using default message size, 256-bits')
return DEFAULT_SIZE
- elif (size not in modes):
+ elif (size not in SIZES):
print('Error: Message size must be \
224, 256, 384, or 512 for {}'.format(func))
sys.exit()
@@ -71,7 +64,7 @@ def check_function(func, size):
def format_output(msg, fmt):
- """Formats the hash value according to the user's choice
+ """FORMATS the hash value according to the user's choice
@msg: the string to be formatted
@fmt: the target format
"""
@@ -162,8 +155,8 @@ def get_options(args=sys.argv[1:]):
help='Message length in bytes 224, 256, 384, 512 '
'(only valid for sha 2 and 3).')
parser.add_argument('-f', '--format',
- choices=formats,
- default=formats[0],
+ choices=FORMATS,
+ default=FORMATS[0],
help='Formatting for the output')
parser.add_argument('-v', '--verbose',
action='store_true',
@@ -171,7 +164,7 @@ def get_options(args=sys.argv[1:]):
output. Without this flag, the program will just \
print the hash')
parser.add_argument('function',
- choices=algos,
+ choices=ALGOS,
help='Use the specified hash function')
return parser.parse_args(args)
diff --git a/fhash/tests/shattered/TESTING b/fhash/tests/TESTING
index bddd76e..a06269f 100644
--- a/fhash/tests/shattered/TESTING
+++ b/fhash/tests/TESTING
@@ -1,3 +1,10 @@
+## **Run `python run_tests.py` to test all files**
+
+All hashes verified with openssl in hashes.json
+
+## Bonus
+Shattered test
+(mostly for fun)
These files should yield the same sha1 hash value
To test run
diff --git a/fhash/tests/basic/TESTING b/fhash/tests/basic/TESTING
deleted file mode 100644
index bc1d926..0000000
--- a/fhash/tests/basic/TESTING
+++ /dev/null
@@ -1,4 +0,0 @@
-Per openssl the sha1 hashes should be:
-
-smolgrownup.png: a7032fda513d3ad28d083599fa227088b2f66062
-textfile: a4a05cfdc38bf07fcaeb1f7de1bc8ae8e783c373
diff --git a/fhash/tests/shattered/shattered-1.pdf b/fhash/tests/files/shattered-1.pdf
index ba9aaa1..ba9aaa1 100644
--- a/fhash/tests/shattered/shattered-1.pdf
+++ b/fhash/tests/files/shattered-1.pdf
Binary files differ
diff --git a/fhash/tests/shattered/shattered-2.pdf b/fhash/tests/files/shattered-2.pdf
index b621eec..b621eec 100644
--- a/fhash/tests/shattered/shattered-2.pdf
+++ b/fhash/tests/files/shattered-2.pdf
Binary files differ
diff --git a/fhash/tests/basic/smolgrownup.png b/fhash/tests/files/smolgrownup.png
index 328a97c..328a97c 100644
--- a/fhash/tests/basic/smolgrownup.png
+++ b/fhash/tests/files/smolgrownup.png
Binary files differ
diff --git a/fhash/tests/basic/textfile b/fhash/tests/files/textfile
index f8c4bf1..f8c4bf1 100644
--- a/fhash/tests/basic/textfile
+++ b/fhash/tests/files/textfile
diff --git a/fhash/tests/hashes.json b/fhash/tests/hashes.json
new file mode 100644
index 0000000..7a4b281
--- /dev/null
+++ b/fhash/tests/hashes.json
@@ -0,0 +1,50 @@
+{
+ "smolgrownup.png":{
+ "md5":"2ceff9dd6abd31842156d6ff84efdaa7",
+ "sha1":"a7032fda513d3ad28d083599fa227088b2f66062",
+ "sha2-224":"01ef7921f29979fc94bf036699aa9259af46549eefb24b09115c704e",
+ "sha2-256":"c801e0c07ac6cf6e51b9aa8c3130fa153223f4f7ed32c7b2f8e05f4c14ab0505",
+ "sha2-384":"8c0a954ca172094c88a58ff4955e91b99ce16c009965fa465f8ffe6d01c89ef7eb030198b23ab6e9754fb5dce3051051",
+ "sha2-512":"bbefbf72110f1432b614fca850e4b3b2f9124e3e290ce096a3d64715f55c3f2d8593b2987fe91927178bcca9a060344449b2c291e8419e441604459727bd6a1c",
+ "sha3-224":"e266f6ee4ace9c657a70a9f2f7e7c49ab0294b4b0f1838a1ae1dad5a",
+ "sha3-256":"10469ad60320cecb2f74ddd131e1b22644b280b339e90e8079a8b250c80b2045",
+ "sha3-384":"d41a34866fa0f2836a8885ab5a18cecdebc87a1199fc1f4bdafb9f6e8c158271954f1a629700d7e1231f8b4dca9f5279",
+ "sha3-512":"9f7c4a0bd8323b4543b93174d4ef60702681a7d4e0704731338fbbdf129e314ca67a690674582bf2ecf1ff3d6fa46015e151dc4c1334c4eaa36ca4d38685c65a"
+ },
+ "textfile":{
+ "md5":"c55b24ebcfd61e3eed1c287498b5d405",
+ "sha1":"a4a05cfdc38bf07fcaeb1f7de1bc8ae8e783c373",
+ "sha2-224":"3adbc273365c2b25c7f877e31e68fb383aedc04ce49af94ad7ec98b8",
+ "sha2-256":"fda4efdbbe9670fb57420fe93bd1d12291e91bc5a828dc704850351a6e7627d0",
+ "sha2-384":"64fb993969b8a01b4f062ba9c0d4253f12a0cc7ae3121a19bcb068d65ec7412dcd1956fea31074639ef37bd23f436445",
+ "sha2-512":"9a78b183d1365f4fc24189753d3dbc4fa0fa93f24c1da630139000d9bd5f498df1b416dc67c2110eec14060472f78c8b30fc46c219170bdd391eb8cb148e9357",
+ "sha3-224":"190165463dc7b73450c6c3f93824b824f3090cd264bc9d40d7147c2e",
+ "sha3-256":"976fe8d779f656f007193170f287649b32dc139307b96f5c12074d1da243dbdd",
+ "sha3-384":"9b056496363a96c8e5871614fc66412ec5cf15b105b40ce747458bb9d749855c4a2c9ca0793bc7500265c9e3bcdefd0c",
+ "sha3-512":"740aacff17ce16f08aabb31f43ed0a3793294770b1e473305023b5386e97eb5bde739eefc3b213626d18cfab4cf1fd861f73fa9eba7a0ff3ec1d58bb3c77b4fe"
+ },
+ "shattered-1.pdf":{
+ "md5":"ee4aa52b139d925f8d8884402b0a750c",
+ "sha1":"38762cf7f55934b34d179ae6a4c80cadccbb7f0a",
+ "sha2-224":"c40f403b2fc59038db8e1add178b5959087414bcb351b5a53941245c",
+ "sha2-256":"2bb787a73e37352f92383abe7e2902936d1059ad9f1ba6daaa9c1e58ee6970d0",
+ "sha2-384":"27f937a0849be559affa109f97744024bc494b2b81dcd9684845cd14574953cc6310398b89e150ad3819188309e59996",
+ "sha2-512":"3c19b2cbcf72f7f5b252ea31677b8f2323d6119e49bcc0fb55931d00132385f1e749bb24cbd68c04ac826ae8421802825d3587fe185abf709669bb9693f6b416",
+ "sha3-224":"b64f1ab973c135c3fe930deb953346790072781f09a831397fe39274",
+ "sha3-256":"bdf57578bea12c08aece823fed38266c9d9b7767e1d25d66083f3b5ac8196e92",
+ "sha3-384":"f2796edd296f764756ddcfbc8f3ca2f55550f8404e064fe6a3104e38dd96eee4f109dc0240ca2764fb9c581617acfa8b",
+ "sha3-512":"347732c4adcfc0c15c1ee543033ae13e75859f6aec5cc940d31af78d1d6fa343f68d6c19702ffb896ad03ca7df2f255c3e12bbd517029489eb89c563fd198771"
+ },
+ "shattered-2.pdf":{
+ "md5":"5bd9d8cabc46041579a311230539b8d1",
+ "sha1":"38762cf7f55934b34d179ae6a4c80cadccbb7f0a",
+ "sha2-224":"672002f3021d3a5b6f90b8e6e4cf26a533de0d869ff047a55a2d019a",
+ "sha2-256":"d4488775d29bdef7993367d541064dbdda50d383f89f0aa13a6ff2e0894ba5ff",
+ "sha2-384":"e04944841a251d5bbed5dbb0d07486d254bcddd2c11341ee9bb045bfd678aa7b784e1b7a7d56ece5d5ede17e143ffe2b",
+ "sha2-512":"f39a04842e4b28e04558496beb7cb84654ded9c00b2f873c3ef64f9dfdbc760cd0273b816858ba5b203c0dd71af8b65d6a0c1032e00e48ace0b4705eedcc1bab",
+ "sha3-224":"0fbd8cceb45899be757091df215775d37af38df67f18fbf70f04e1aa",
+ "sha3-256":"d89bdc94e5f1d1f7aee9554783558aa5eaeb5c3e0393e27ed9ad1ff26711b319",
+ "sha3-384":"87bbdbde26eb1fdb9b719fe6f0b23828d65621073adb710aba2db00e975d5ce900d28a384167689c1fb0cc870f930ef5",
+ "sha3-512":"9ba3b6bea68399f58fd56ce90e3bae603c3adb1e0893f57c641967c7e9f8e30d59e66acc7c571e73e0379927874661d9b5ee5f228243c098ec2b1e53d45cd913"
+ }
+}
diff --git a/fhash/tests/run_tests.py b/fhash/tests/run_tests.py
new file mode 100644
index 0000000..de78c06
--- /dev/null
+++ b/fhash/tests/run_tests.py
@@ -0,0 +1,62 @@
+import sys
+import json
+import unittest
+import subprocess
+sys.path.append('..')
+import fhash
+
+class TestFhash(unittest.TestCase):
+ # these files were teseted with openssl
+ HASHES = json.load(open('hashes.json'))
+ FHASH = "../fhash.py"
+ DIR = "files/"
+
+
+ def test_shattered(self):
+ """Just for fun, two files that have the same hash, breaking sha1"""
+ SHATTERED = '38762cf7f55934b34d179ae6a4c80cadccbb7f0a'
+ cmd = [self.FHASH, 'sha1', '-i', self.DIR + 'shattered-1.pdf']
+ shat1 = subprocess.check_output(cmd).strip().decode()
+ cmd[3] = self.DIR + 'shattered-2.pdf'
+ shat2 = subprocess.check_output(cmd).strip().decode()
+ self.assertTrue(shat1 == shat2 == SHATTERED)
+
+
+ def test_file_types(self):
+ """Tests that hashes for different file types are correct.
+ Uses sha1"""
+ for k in self.HASHES.keys():
+ cmd = [self.FHASH, 'sha1', '-i', self.DIR + k]
+ fh = subprocess.check_output(cmd).strip().decode()
+ ssl = self.HASHES[k]['sha1']
+ self.assertFalse(ssl != fh,
+ f"{k}:{fh} did not match the correct hash: {ssl}"
+ )
+
+ def test_algos(self):
+ """Tests that hashes for different algorithms and sizes are correct.
+ """
+
+ for k in self.HASHES.keys():
+ for alg in fhash.ALGOS:
+ if alg == 'md5' or alg == 'sha1':
+
+ cmd = [self.FHASH, alg, '-i', self.DIR + k]
+ fh = subprocess.check_output(cmd).strip().decode()
+ ssl = self.HASHES[k][alg]
+ self.assertFalse(ssl != fh,
+ f"{k}:{fh} did not match the correct hash: {ssl}"
+ )
+ else:
+ for s in fhash.SIZES:
+ cmd = [self.FHASH, alg, '-i', self.DIR + k, '-s',
+ str(s)]
+ fh = subprocess.check_output(cmd).strip().decode()
+ ssl = self.HASHES[k][alg + '-' + str(s)]
+ self.assertFalse(ssl != fh,
+ f"{k}:{fhash} did not match the correct hash: {ssl}"
+ )
+
+
+if __name__ == '__main__':
+ unittest.main()