-
Notifications
You must be signed in to change notification settings - Fork 0
/
protocol.py
82 lines (65 loc) · 2.2 KB
/
protocol.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
"""A mod to handle dump/load from images"""
import hashlib
import io
import coder
HASHSIZE = 32
LENTHSIZE = 16 # 64bit unsigned int (to record file size)
CHUNKSIZE = 4096
HEADSIZE = HASHSIZE*2 + LENTHSIZE
ORDER = 'big'
class CurruptedError(ValueError):
"""Currupt data or hash."""
pass
def dumps(b, fimg):
f = io.BytesIO(b)
dump(f,fimg)
def loads(fimg):
f=io.BytesIO()
load(f,fimg)
f.seek(0)
return f.read()
def dump(fin, fimg: coder.ImageFile):
# write body while recoding the hash and lenth
size = 0
digest = hashlib.sha256()
fimg.seek(HEADSIZE)
for b in iter(lambda: fin.read(CHUNKSIZE), b''):
size+=len(b)
digest.update(b)
if size+HEADSIZE > fimg.size:
raise ValueError("File too big to be packed into image.")
elif size> 256**LENTHSIZE:
raise ValueError("Filesize too big to be packed into 64bit \
unsigned int")
fimg.write(b)
# write the head
fimg.seek(0)
size_as_bytes = size.to_bytes(LENTHSIZE, ORDER, signed = False)
fimg.write(size_as_bytes)
fimg.write(hashlib.sha256(size_as_bytes).digest())
fimg.write(digest.digest())
def load(fout, fimg: coder.ImageFile):
# read file size
size_as_bytes = fimg.read(LENTHSIZE)
size_hash_excepted = hashlib.sha256(size_as_bytes).digest()
size_hash_got = fimg.read(HASHSIZE)
if size_hash_excepted != size_hash_got:
raise CurruptedError("Currupt size(excepted hash different from \
got hash)")
size = int.from_bytes(size_as_bytes, ORDER, signed=False)
if size + HEADSIZE>fimg.size:
raise CurruptedError("Currupt size(size to big to be fit into image)")
# read hash and body
hash_excepted = fimg.read(HASHSIZE)
digest = hashlib.sha256()
for i in range(size//CHUNKSIZE):
chunk = fimg.read(CHUNKSIZE)
digest.update(chunk)
fout.write(chunk)
chunk = fimg.read(size%CHUNKSIZE)
digest.update(chunk)
fout.write(chunk)
hash_got = digest.digest()
if hash_excepted != hash_got:
raise CurruptedError("Currupt data(excepted hash different from \
got hash)")