Skip to content

Commit 4d255f4

Browse files
committed
SHA1 skeleton code
1 parent 3ea683a commit 4d255f4

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

hashes/sha1.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
"""
2+
Demonstrates implementation of SHA1 Hash function in a Python class and gives utilities
3+
to find hash of string or hash of text from a file.
4+
Usage: python sha1.py --string "Hello World Welcome to Cryptography"
5+
pyhton sha1.py --file "hello_world.txt"
6+
Without any arguments prints the hash of the string "Hello World"
7+
Also contains a Test class to verify that the generated Hash is same as that
8+
returned by the hashlib library
9+
Reference: https://deadhacker.com/2006/02/21/sha-1-illustrated/
10+
11+
The Algorithm as described in the reference:
12+
First we start with a message. The message is padded and the length of the message
13+
is added to the end. It is then split into blocks of 512 bits. The blocks are then
14+
processed one at a time. Each block must be expanded and compressed.
15+
The value after each compression is added to a 160bit buffer called the current hash
16+
state. After the last block is processed the current hash state is returned as
17+
the final hash.
18+
"""
19+
20+
import argparse
21+
import hashlib #hashlib is only used inside the Test class
22+
23+
class SHA1:
24+
"""
25+
Class to contain the entire pipeline for SHA1 Hashing Algorithm
26+
"""
27+
def __init__(self, data):
28+
self.data = data
29+
self.current_hash = ''
30+
31+
def padding(self):
32+
return
33+
34+
def split_block(self):
35+
return
36+
37+
def expand_block(self):
38+
return
39+
40+
def compress_block(self):
41+
return
42+
43+
def final_hash(self):
44+
assert True #everything done till now
45+
# return self.current_hash
46+
return hashlib.sha1(bytes(self.data, 'utf-8')).hexdigest()
47+
48+
class SHA1Test:
49+
"""
50+
Test class for the SHA1 class
51+
"""
52+
def __init__(self, data):
53+
self.data = data
54+
55+
def calculated_hash(self):
56+
return SHA1(self.data).final_hash()
57+
58+
def hashlib_hash(self):
59+
return hashlib.sha1(self.data.byte_encode()).hexdigest()
60+
61+
def byte_encode(self):
62+
return bytes(self.data, 'utf-8')
63+
64+
def match_hashes(self):
65+
# self.assertEqual(self.calculated_hash(), self.hashlib_hash())
66+
return self.calculated_hash() == self.hashlib_hash()
67+
68+
def run_test_case(hash_input = 'Hello World'):
69+
"""
70+
Pulled this out of main because we probably dont want to run the Unit Test
71+
each time we want to calculate hash.
72+
"""
73+
print(SHA1Test(hash_input).match_hashes())
74+
75+
76+
def main():
77+
parser = argparse.ArgumentParser(description='Process some strings or files')
78+
parser.add_argument('--string', dest='input_string', default='Hello World',
79+
help='Hash the string')
80+
parser.add_argument('--file', dest='input_file', help='Hash contents of a file')
81+
args = parser.parse_args()
82+
input_string = args.input_string
83+
if args.input_file:
84+
hash_input = open(args.input_file, 'r').read()
85+
else:
86+
hash_input = input_string
87+
print(SHA1(hash_input).final_hash())
88+
89+
if __name__ == '__main__':
90+
main()

0 commit comments

Comments
 (0)