diff --git a/P2/main.py b/P2/main.py index 223489c..defe11c 100644 --- a/P2/main.py +++ b/P2/main.py @@ -1,5 +1,5 @@ -import random import matplotlib.pyplot as plt +import numpy as np # Linear Feedback Shift Register @@ -53,14 +53,23 @@ def CRC_Parity(s, g): def channel_bsc(p, n): - f = "" + errors = "" for i in range(n): - p_i = random.random() - # p_i <= p ? F += "1" : F += "0" - f += "1" if p_i <= p else "0" + errors += "1" if np.random.random() < p else "0" - return f + return errors + + +def send_channel(p, codeword, error_pattern): + received = "" + + for j in range(len(codeword)): + bit1 = int(codeword[j]) + bit2 = int(error_pattern[j]) + received += str(bit1 ^ bit2) + + return received def p_k_Fehler(p): @@ -93,22 +102,133 @@ def p_k_Fehler(p): plt.show() +def optimal_blocksize(p, word, poly): + crc_bits = len(poly) - 1 + n = len(word) + + best_datasize = float('inf') + best_blocksize = 0 + + for i in range(10): + block_size_i = 2 ** i + if block_size_i < n: + blocks = n / block_size_i + codeword_size = block_size_i + crc_bits + p_succesful = (1 - p) ** codeword_size + block_avrg_reps = 1 / p_succesful + block_avrg_datasize = codeword_size * block_avrg_reps + + total_avrg_datasize = block_avrg_datasize * blocks + if total_avrg_datasize < best_datasize: + best_datasize = total_avrg_datasize + best_blocksize = block_size_i + + return best_blocksize + + +def generate_random_binary(n): + bin_string = "" + + for i in range(n): + bin_string += "1" if np.random.random() < 0.5 else "0" + + return bin_string + + +def split_into_blocks(word, block_size): + blocks = [] + + for i in range(0, len(word), block_size): + block = word[i:i + block_size] + blocks.append(block) + + return blocks + + def main(): p = 0.1 + n = 1000 + + detected_blocks = 0 + repeats = 0 + total_errors = 0 + total_transmited_data = 0 # LSB -> MSB - s = "110011101100101" + # s = "110011101100101" + word = generate_random_binary(n) # MSB -> LSB - g = "100101" + poly = "100101" - prf = CRC_Parity(s, g) - print(prf) + blocksize = optimal_blocksize(p, word, poly) - print(channel_bsc(p, 15)) + blocks = split_into_blocks(word, blocksize) p_k_Fehler(p) + for i, block in enumerate(blocks): + # CRC-Codierung + crc_bits = CRC_Parity(block, poly) + codeword = crc_bits + block + + # BSC-Kanal + error_pattern = channel_bsc(p, len(codeword)) + received = send_channel(p, codeword, error_pattern) + + # Fehlerprüfung + check = CRC_Parity(received, poly) + + print(f"==========BLOCK {i + 1}==========") + print(f" Codewort: {codeword}") + print(f" Empfangen: {received}") + + detected_blocks += 1 if "1" in check else 0 + total_transmited_data += len(codeword) + repeats += 1 + + if "1" in check: + print(" ❌ Fehler ") + total_errors += error_pattern.count("1") + else: + print(" ✅ Erfolgreich") + + + ''' + Version in der fehlerhafte Übertragungen so lange wiederholt werden, bis sie fehlerfrei sind + ''' + + ''' + while "1" in check: + print(" ❌ Fehler ") + total_errors += error_pattern.count("1") + + # erneute Übertragung + repeats += 1 + total_transmited_data += len(codeword) + error_pattern = channel_bsc(p, len(codeword)) + received = send_channel(p, codeword, error_pattern) + check = CRC_Parity(received, poly) + print(f" Empfangen: {received}") + + print(" ✅ Erfolgreich \n") + + ''' + + + # Ende + print("============ ERGEBNISSE ============") + print(f"ursprüngliche Datenmenge: {n} Bits") + print(f" p: {p * 100} %") + print(f" generator Polynom: {poly}") + print(f" Blockgröße: {blocksize}") + print(f" Blockanzahl: {len(blocks)}") + print(f" übertragene Datenmenge: {total_transmited_data} Bit") + print( + f" fehlerfreie Blöcke: {len(blocks) - detected_blocks} = {((len(blocks) - detected_blocks) / len(blocks) * 100):.2f} %") + print(f" Wiederholungen: {repeats}, ca. {(repeats / len(blocks)):.1f} p.Bl.") + print(f" fehlerhafte Bits: {total_errors} Bit = {(total_errors / total_transmited_data * 100):.2f}%") + if __name__ == '__main__': main()