parent
419be2bb94
commit
d72e042ce2
@ -1,3 +1,23 @@
|
|||||||
# sha1
|
# nsha1
|
||||||
|
|
||||||
SHA1 in C
|
This was a failed attempt to create SHA1 algorithm in C. The algorithm achieved still seems sensitive to small changes in text files. So maybe it can be used in stuff like VCS and build systems.
|
||||||
|
|
||||||
|
## How to use
|
||||||
|
|
||||||
|
This is a single header project. Only nsha1.h needs to be included. Usage is shown in **example.c** file. So there are only 2 source files, nsha1.h and example.c
|
||||||
|
To compile :
|
||||||
|
|
||||||
|
```
|
||||||
|
python3 flow
|
||||||
|
```
|
||||||
|
|
||||||
|
To clean:
|
||||||
|
```
|
||||||
|
python3 flow clean
|
||||||
|
```
|
||||||
|
|
||||||
|
The "library" is only adding:
|
||||||
|
|
||||||
|
1. NSHA1_Result strcut to store result
|
||||||
|
2. nsha1file, a function to get nsha1 of a file.
|
||||||
|
3. leftRotate32, a macro to circular shift 32 bit unsigned integers.
|
@ -0,0 +1,4 @@
|
|||||||
|
output.flow
|
||||||
|
;!remove!;
|
||||||
|
a.out
|
||||||
|
output.flow.temp
|
@ -1,20 +1,10 @@
|
|||||||
#include "sha1.h"
|
#include "nsha1.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
SHA1_Result r = sha1file("dummyFile");
|
NSHA1_Result r = nsha1file("flow");
|
||||||
char buffer[41];
|
char buffer[41];
|
||||||
|
printf("%x %x %x %x %x", r.h0, r.h1, r.h2, r.h3, r.h4);
|
||||||
// final 160 bit hash value is :
|
|
||||||
// (h0 << 128) | (h1 << 96) | (h2 << 64) | (h3 << 32) | h4
|
|
||||||
// but since c does not support ints bigger than 64 bit, we will just print the values of all h(i)'s
|
|
||||||
sprintf(buffer, "%x%x%x%x%x", r.h0, r.h1, r.h2, r.h3, r.h4);
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
while(buffer[i] != '\0')
|
|
||||||
printf("%c", buffer[i++]);
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,217 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import os # for checking if file exists
|
||||||
|
import hashlib # for md5sum
|
||||||
|
import sys # for reading cmd args
|
||||||
|
import shutil # for removind directories recursively
|
||||||
|
from subprocess import run # running external programs
|
||||||
|
|
||||||
|
build_files_src = {}
|
||||||
|
build_files_level = {}
|
||||||
|
build_files_toBuild = {}
|
||||||
|
|
||||||
|
# Taken from https://www.asciiart.eu/nature/deserts
|
||||||
|
done_art = r"""
|
||||||
|
. _ + . ______ . .
|
||||||
|
( /|\ . | \ . +
|
||||||
|
. ||||| _ | | | | || .
|
||||||
|
. ||||| | | _| | | | |_|| .
|
||||||
|
/\ ||||| . | | | | | | .
|
||||||
|
__||||_|||||____| |_|_____________\__________
|
||||||
|
. |||| ||||| /\ _____ _____ . .
|
||||||
|
|||| ||||| |||| . . . ________
|
||||||
|
. \|`-'|||| |||| __________ . .
|
||||||
|
\__ |||| |||| . . .
|
||||||
|
__ ||||`-'||| . . __________
|
||||||
|
. . |||| ___/ ___________ .
|
||||||
|
. _ ||||| . _ . _________
|
||||||
|
_ ___|||||__ _ \\--// . _
|
||||||
|
_ `---' .)=\oo|=(. _ . . .
|
||||||
|
_ ^ . - . \.|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def check_if_file(filename, build_file_name):
|
||||||
|
""" Checks it the given file exists, else print error and exit """
|
||||||
|
if os.path.isfile(filename):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print("In " + build_file_name + " : " + filename + " is not a file")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
def getmd5(filename):
|
||||||
|
""" Takes Path to a file and get it's md5sum """
|
||||||
|
with open(filename, 'rb') as file_to_check:
|
||||||
|
data = file_to_check.read()
|
||||||
|
md5_returned = hashlib.md5(data).hexdigest()
|
||||||
|
return md5_returned
|
||||||
|
|
||||||
|
def get_meta_file(filename):
|
||||||
|
""" Takes src file name in build file and converts it to entry in .flow folder filename """
|
||||||
|
fname = ""
|
||||||
|
for letter in filename:
|
||||||
|
if letter == "." or letter == "\\" or letter == "/":
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
fname += letter
|
||||||
|
return fname
|
||||||
|
|
||||||
|
def update_md5(filename):
|
||||||
|
""" Takes the filename in .flow as var fname and updates it's md5sum value according to contents of var filename """
|
||||||
|
fname = get_meta_file(filename)
|
||||||
|
with open(".flow/" + fname, "w") as f:
|
||||||
|
f.write(getmd5(filename).strip())
|
||||||
|
|
||||||
|
def create_md5(filename):
|
||||||
|
""" Takes the filename in .flow as var fname and updates it's md5sum value according to contents of var filename """
|
||||||
|
fname = get_meta_file(filename)
|
||||||
|
with open(".flow/" + fname, "w") as f:
|
||||||
|
f.write("new file")
|
||||||
|
|
||||||
|
def getstoredmd5(filename):
|
||||||
|
""" get value of file's md5 from .flow folder, else create entry. return the (md5, createdEntry)"""
|
||||||
|
md5_returned = ""
|
||||||
|
fname = get_meta_file(filename)
|
||||||
|
if fname in os.listdir(".flow"):
|
||||||
|
with open(".flow/" + fname, "r") as f:
|
||||||
|
md5_returned = f.readline()
|
||||||
|
else:
|
||||||
|
print("INFO : md5sum entry not present for " + filename + " creating one.")
|
||||||
|
create_md5(filename)
|
||||||
|
return md5_returned
|
||||||
|
|
||||||
|
def recieved_file(filename, level, rebuild):
|
||||||
|
if build_files_toBuild.get(filename, False) == False:
|
||||||
|
build_files_toBuild[filename] = rebuild
|
||||||
|
if build_files_level.get(filename, -1) < level:
|
||||||
|
build_files_level[filename] = level
|
||||||
|
pass
|
||||||
|
|
||||||
|
start, mid, end = "", "", ""
|
||||||
|
with open(filename, "r") as f:
|
||||||
|
x = f.read().split(";!run!;")
|
||||||
|
start = x[0]
|
||||||
|
y = x[1].split(";!end!;")
|
||||||
|
mid = y[0]
|
||||||
|
end = y[1]
|
||||||
|
|
||||||
|
# start
|
||||||
|
src_files = []
|
||||||
|
for line in start.split():
|
||||||
|
entry = line.strip()
|
||||||
|
src_files.append(entry)
|
||||||
|
|
||||||
|
build_files_src[filename] = src_files
|
||||||
|
|
||||||
|
if rebuild:
|
||||||
|
build_files_toBuild[filename] = True
|
||||||
|
else:
|
||||||
|
for line in start.split():
|
||||||
|
entry = line.strip()
|
||||||
|
check_if_file(entry, filename)
|
||||||
|
new_md5, old_md5 = "", ""
|
||||||
|
new_md5 = getmd5(entry)
|
||||||
|
old_md5 = getstoredmd5(entry)
|
||||||
|
|
||||||
|
if old_md5 != new_md5:
|
||||||
|
print(entry + " was modified")
|
||||||
|
build_files_toBuild[filename] = True
|
||||||
|
|
||||||
|
# mid
|
||||||
|
if build_files_toBuild[filename]:
|
||||||
|
with open(filename + ".temp", "w") as f:
|
||||||
|
f.write(mid)
|
||||||
|
|
||||||
|
# end
|
||||||
|
for line in end.split():
|
||||||
|
entry = line.strip()
|
||||||
|
check_if_file(entry, filename)
|
||||||
|
recieved_file(entry, level + 1, build_files_toBuild[filename])
|
||||||
|
|
||||||
|
|
||||||
|
def remove_if_exists(filename):
|
||||||
|
""" Check if the given filename exists, if yes then print filename and delete """
|
||||||
|
if os.path.isfile(filename):
|
||||||
|
print("Deleting " + filename)
|
||||||
|
os.remove(filename)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
with open("build.flow", "r") as main_build_file:
|
||||||
|
""" flow clean """
|
||||||
|
for i in sys.argv:
|
||||||
|
if i == "clean":
|
||||||
|
# delete the .flow folder
|
||||||
|
if os.path.exists(".flow"):
|
||||||
|
print("Removing .flow directory")
|
||||||
|
shutil.rmtree(".flow")
|
||||||
|
|
||||||
|
# delete the mentioned files
|
||||||
|
cleaning_started = False
|
||||||
|
for line in main_build_file:
|
||||||
|
entry = line.strip()
|
||||||
|
if cleaning_started:
|
||||||
|
remove_if_exists(entry)
|
||||||
|
if entry == ";!remove!;":
|
||||||
|
cleaning_started = True
|
||||||
|
print("Cleaning done")
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
if not os.path.exists(".flow"):
|
||||||
|
os.makedirs(".flow")
|
||||||
|
|
||||||
|
""" creating data for build process """
|
||||||
|
for line in main_build_file:
|
||||||
|
entry = line.strip()
|
||||||
|
|
||||||
|
if entry == ";!remove!;":
|
||||||
|
break
|
||||||
|
elif os.path.isfile(entry):
|
||||||
|
recieved_file(entry, 0, False)
|
||||||
|
else:
|
||||||
|
print("ERROR : " + entry + " is neither a file or a directory")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
print(build_files_level)
|
||||||
|
print(build_files_src)
|
||||||
|
print(build_files_toBuild)
|
||||||
|
print()
|
||||||
|
print("<-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <->")
|
||||||
|
print()
|
||||||
|
|
||||||
|
""" Build by using the data """
|
||||||
|
for f, x in list(build_files_toBuild.items()):
|
||||||
|
if x == False:
|
||||||
|
del build_files_level[f]
|
||||||
|
del build_files_src[f]
|
||||||
|
del build_files_toBuild[f]
|
||||||
|
|
||||||
|
levels_list = []
|
||||||
|
for f,x in build_files_level.items():
|
||||||
|
levels_list.append((f,x))
|
||||||
|
|
||||||
|
n = len(levels_list)
|
||||||
|
for i in range(n):
|
||||||
|
for j in range(0, n-i-1):
|
||||||
|
if levels_list[j][1] > levels_list[j+1][1]:
|
||||||
|
levels_list[j], levels_list[j+1] = levels_list[j+1], levels_list[j]
|
||||||
|
|
||||||
|
for item in levels_list:
|
||||||
|
p = run([ "bash", item[0] + ".temp" ])
|
||||||
|
if p.returncode != 0:
|
||||||
|
print(p)
|
||||||
|
print("Build Failed", file=sys.stderr )
|
||||||
|
exit(p.returncode)
|
||||||
|
|
||||||
|
for item in levels_list:
|
||||||
|
build_file_name = item[0]
|
||||||
|
for src_file in build_files_src[build_file_name]:
|
||||||
|
update_md5(src_file)
|
||||||
|
|
||||||
|
print(done_art)
|
||||||
|
print("Build Completed Successfully")
|
||||||
|
print()
|
||||||
|
print("<-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <->")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -0,0 +1,5 @@
|
|||||||
|
example.c
|
||||||
|
nsha1.h
|
||||||
|
;!run!;
|
||||||
|
gcc example.c
|
||||||
|
;!end!;
|
Loading…
Reference in New Issue