-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
executable file
·109 lines (97 loc) · 3.21 KB
/
main.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/env python
#
# Decode binary message in Bush's 'Sixteen Stone' album cover.
#
PO = False # 'print out'
#
# test.data has ASCII chars 7 bits long. To decode, set DATA_FILE to
# "test.data", bit_size to 7 and do not reverse bits.
#
DATA_FILE = "cover.data"
def get_file_lines():
fh = open(DATA_FILE, "r")
lines = []
for line in fh:
lines.append(line)
fh.close()
return lines
def get_file_string(reverse=False):
lines = []
with open(DATA_FILE, "r") as fh:
for line in fh:
lines.append(line.strip())
lines = reverse and reversed(lines) or lines
return "".join(lines)
def get_char(binary, one_or_zero):
binary = binary.replace("?", one_or_zero)
intval = int(binary, 2)
char = chr(intval)
return char, intval
def get_letter(binary):
char0, intval0 = get_char(binary, "0")
char1, intval1 = get_char(binary, "1")
char = None
intval = None
if char0 == char1:
char = char0
intval = intval0
else:
char = "({}|{})".format(char0, char1)
intval = [intval0, intval1]
if PO: print "Binary:", binary, "Int:", intval, "Char:", char
return char
def rev(val):
return val[::-1]
def alg_num1(string, bit_size):
if PO: print "String:", string, "len:", len(string)
start = bit_size * -1
offset = len(string)
letters = []
while offset > 0:
bits = string[start:offset]
if not bits: break
#print "bits:", bits, "start:", start, "offset:", offset, "size:", bit_size
letters.append(get_letter(bits))
start = start - bit_size
offset = offset - bit_size
print "Message:", "".join(letters)
def alg_num2(string, bit_size):
if PO: print "String:", string, "len:", len(string)
start = bit_size * -1
offset = len(string)
letters = []
while offset > 0:
bits = string[start:offset]
if not bits: break
#print "bits:", bits, "start:", start, "offset:", offset, "size:", bit_size
letters.append(get_letter(bits))
start = start - bit_size
offset = offset - bit_size
print "Message:", "".join(letters)
#
# Algorithms
#
# Last line in data:
# 0110111000110
#
#
# 1. Each chunk is N bits long reading left to right, decoding (of course) from
# right to left:
# - If bit is 7, then bits are read as 0110111 000110? <- '?' would contain a bit from the next line, if there was one
#
# 2. Each chunk is N bits long reading right to left, decoding from right to
# left:
# - If bit is 7, then bits are read as 0110001 110110? <- Again, '?' would contain next line's bit, if it existed
#
# An option was added to read the file from either left to right (top to bottom)
# (reverse=False) or read right to left (bottom to top) (reverse=True)
#
# For bits that are unknown, both characters are decoded when the bit is '0'
# or '1'. It is denoted as (L|R) where L denotes if the bit is '0', R denotes
# when the bit is '1'. As an example, you may see something like '(A|B)'. 'A' is
# what the char would be if the bit was '0', 'B' if '1'.
#
print("Alg #1 - File is read forward")
alg_num1(get_file_string(reverse=False), 7)
print("Alg #1 - File is read reversed")
alg_num1(get_file_string(reverse=True), 7)