decoder codebook integrated as header into message
This commit is contained in:
61
main.py
61
main.py
@@ -2,7 +2,7 @@ import math
|
||||
|
||||
|
||||
def Q_statistik():
|
||||
with open('Text.txt', 'r', encoding='utf-8') as file:
|
||||
with open('Text.txt', 'r', encoding='latin-1') as file:
|
||||
text = file.read()
|
||||
|
||||
freq = {}
|
||||
@@ -27,11 +27,10 @@ def Q_statistik():
|
||||
|
||||
|
||||
def fano_encoder(probabilities):
|
||||
# Key = probability im Dictionary
|
||||
sorted_probs = sorted(probabilities.items(), key=lambda x: x[1], reverse=True)
|
||||
|
||||
def fano_recursive(symbols):
|
||||
if len(symbols) == 1: # Keine neuen Teilmengen möglich
|
||||
if len(symbols) == 1:
|
||||
return {symbols[0][0]: ""}
|
||||
|
||||
total = sum([symbol[1] for symbol in symbols])
|
||||
@@ -60,21 +59,68 @@ def fano_encoder(probabilities):
|
||||
return fano_recursive(sorted_probs)
|
||||
|
||||
|
||||
def Q_Fanoencoder(input_path='Text.txt', output_path='EncodedText.txt'):
|
||||
def Q_Fanoencoder():
|
||||
_, probabilities, _, _ = Q_statistik()
|
||||
fano_codes = fano_encoder(probabilities)
|
||||
|
||||
with open(input_path, 'r', encoding='utf-8') as file:
|
||||
with open('Text.txt', 'r', encoding='latin-1') as file:
|
||||
text = file.read()
|
||||
|
||||
encoded_text = ''.join([fano_codes[char] for char in text])
|
||||
|
||||
with open(output_path, 'w', encoding='utf-8') as file:
|
||||
file.write(encoded_text)
|
||||
coding_table_bin = ''.join(
|
||||
[format(ord(char), '08b') +
|
||||
format(len(code), '08b') +
|
||||
code
|
||||
for char, code in fano_codes.items()]
|
||||
)
|
||||
|
||||
coding_table_length = len(coding_table_bin)
|
||||
header = f'{coding_table_length:016b}' # 2 bytes for the length in binary
|
||||
final_encoded_text = header + coding_table_bin + encoded_text
|
||||
|
||||
with open('EncodedText.txt', 'w', encoding='latin-1') as file:
|
||||
file.write(final_encoded_text)
|
||||
|
||||
return text, encoded_text, fano_codes
|
||||
|
||||
|
||||
def Q_decoder():
|
||||
with open('EncodedText.txt', 'r', encoding='latin-1') as file:
|
||||
encoded_text = file.read()
|
||||
|
||||
coding_table_length = int(encoded_text[:16], 2)
|
||||
|
||||
coding_table_bin = encoded_text[16:16 + coding_table_length]
|
||||
encoded_text = encoded_text[16 + coding_table_length:]
|
||||
|
||||
# Codebuch
|
||||
fano_codes = {}
|
||||
i = 0
|
||||
while i < len(coding_table_bin):
|
||||
char_bin = coding_table_bin[i:i + 8]
|
||||
char = chr(int(char_bin, 2))
|
||||
i += 8
|
||||
code_length_bin = coding_table_bin[i:i + 8]
|
||||
code_length = int(code_length_bin, 2)
|
||||
i += 8
|
||||
code = coding_table_bin[i:i + code_length]
|
||||
fano_codes[code] = char
|
||||
i += code_length
|
||||
|
||||
# Text
|
||||
decoded_text = ''
|
||||
current_code = ''
|
||||
for bit in encoded_text:
|
||||
current_code += bit
|
||||
if current_code in fano_codes:
|
||||
decoded_text += fano_codes[current_code]
|
||||
current_code = ''
|
||||
|
||||
with open('DecodedText.txt', 'w', encoding='latin-1') as file:
|
||||
file.write(decoded_text)
|
||||
|
||||
|
||||
def calculate_compression_rate(original_text, encoded_text, fano_codes):
|
||||
original_length_bits = len(original_text) * 8
|
||||
encoded_length_bits = len(encoded_text)
|
||||
@@ -98,6 +144,7 @@ def main():
|
||||
print(f"Originale Länge in Bits: {original_length_bits}")
|
||||
print(f"Gesamte codierte Länge in Bits (inkl. Codetabelle): {total_encoded_bits}")
|
||||
print(f"Kompressionsrate: {compression_rate:.2f}%")
|
||||
Q_decoder()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user