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()