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

57 lines
1.7 KiB
Python

import numpy as np
import sys
# Character Set and coding
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 encode_message(msg, alphabet=ALPHABET):
msg = msg.strip()
if len(msg) != 40:
raise Exception("Message must be exactly 40 characters!")
# Get Hadamard codes
H = get_hadamard(64)
code_length = 64
# Normalize so signal energy stays bounded
# Each row has norm sqrt(64) = 8, so scale down by 1/8
scale = 1 / np.sqrt(code_length)
signals = []
for c in msg:
idx = alphabet.index(c)
signals.append(H[idx] * scale)
signal = np.concatenate(signals)
# Energy check (should be << 2000)
assert signal.shape[0] == 2560
energy = np.sum(signal ** 2)
if energy > 2000:
raise Exception("Signal energy above allowed!")
return signal
def main():
import argparse
parser = argparse.ArgumentParser(description="Message to signal encoder for PDC Project")
parser.add_argument('--message_file', type=str, required=True, help="Text file with exactly 40 chars.")
parser.add_argument('--output_file', type=str, required=True, help="Output signal file for client.py.")
args = parser.parse_args()
with open(args.message_file, 'r') as f:
msg = f.read().strip()
x = encode_message(msg)
np.savetxt(args.output_file, x)
if __name__ == '__main__':
main()