pdc_project/receiver.py
2025-05-19 19:44:29 +02:00

59 lines
1.9 KiB
Python

import numpy as np
ALPHABET = (
list('abcdefghijklmnopqrstuvwxyz') +
list('ABCDEFGHIJKLMNOPQRSTUVWXYZ') +
list('0123456789') +
[' ', '.']
)
def get_hadamard(n):
assert (n & (n - 1) == 0), "Hadamard order must be power of 2"
H = np.array([[1]])
while H.shape[0] < n:
H = np.block([
[ H, H],
[ H, -H]
])
return H
def decode_signal(signal, alphabet=ALPHABET):
code_length = 64
n_chars = len(signal) // code_length
H = get_hadamard(64)
scale = 1 / np.sqrt(code_length)
codebook = H * scale
decoded = []
for i in range(n_chars):
y = signal[i*code_length : (i+1)*code_length]
# The channel may have applied sqrt(10) gain to odds or evens
# We don't know which, so try both options and pick best
y_even = np.array(y)
y_even[::2] /= np.sqrt(10)
y_odd = np.array(y)
y_odd[1::2] /= np.sqrt(10)
# Try decoding both hypotheses
scores_even = codebook @ y_even
scores_odd = codebook @ y_odd
idx_even = np.argmax(scores_even)
idx_odd = np.argmax(scores_odd)
score_even = np.max(scores_even)
score_odd = np.max(scores_odd)
idx_best = idx_even if score_even > score_odd else idx_odd
decoded.append(alphabet[idx_best])
return ''.join(decoded)
def main():
import argparse
parser = argparse.ArgumentParser(description="Receiver: decode y.txt to recovered message for PDC Project.")
parser.add_argument('--input_file', type=str, required=True, help="Received y.txt from channel/server")
parser.add_argument('--output_file', type=str, required=True, help="Text file for the decoded message")
args = parser.parse_args()
y = np.loadtxt(args.input_file)
decoded = decode_signal(y)
with open(args.output_file, 'w') as f:
f.write(decoded)
if __name__ == '__main__':
main()