QuantumCrypt1 / tab /tab6_noise_simulation.py
raviix46's picture
Update tab/tab6_noise_simulation.py
e2c6594 verified
import gradio as gr
import matplotlib.pyplot as plt
from io import BytesIO
from PIL import Image
import random
# ---------------- Function to add random noise (simulate eavesdropper) ----------------
def add_noise_to_key(key_str, flip_percent=0.1):
"""
Flips 'flip_percent' of bits in the key to simulate eavesdropper noise.
"""
bits = list(key_str.strip())
total_bits = len(bits)
num_flips = int(total_bits * flip_percent)
# Randomly select positions to flip
flip_indices = random.sample(range(total_bits), num_flips)
for i in flip_indices:
bits[i] = '1' if bits[i] == '0' else '0' # Flip the bit
return ''.join(bits), flip_indices # Also return which bits were flipped
# ---------------- Function to compare and plot ----------------
def compare_original_vs_noisy(key_str):
"""
Compares original and noisy QKD keys with a visual plot.
Highlights flipped bits for clarity.
"""
key_str = ''.join([b for b in key_str.strip() if b in '01']) # Clean input
if not key_str:
return None, "⚠️ Invalid input: Please enter a binary key."
noisy_key, flipped_indices = add_noise_to_key(key_str)
total_bits = len(key_str)
heights = [1] * total_bits # Fixed height bars
x = range(total_bits)
fig, axs = plt.subplots(2, 1, figsize=(12, 3.8), sharex=True)
# ---------------- First plot: Original Key (all green) ----------------
axs[0].bar(x, heights, color='green', edgecolor='black', linewidth=0.2)
axs[0].set_title("Before Noise: Original QKD Key", fontsize=11)
axs[0].set_yticks([])
axs[0].set_ylabel("Bit")
# ---------------- Second plot: Noisy Key (red where flipped, green where same) ----------------
colors = ['red' if i in flipped_indices else 'green' for i in range(total_bits)]
axs[1].bar(x, heights, color=colors, edgecolor='black', linewidth=0.2)
axs[1].set_title("After Noise: Key with Eavesdropper Flips", fontsize=11)
axs[1].set_xlabel("Bit Index")
axs[1].set_yticks([])
axs[1].set_ylabel("Bit")
plt.tight_layout()
# Save to buffer and return
buf = BytesIO()
plt.savefig(buf, format='png')
plt.close()
buf.seek(0)
# Generate human-readable summary
corruption_rate = (len(flipped_indices) / total_bits) * 100
summary = f"⚠️ {len(flipped_indices)} bits flipped out of {total_bits}{corruption_rate:.2f}% corruption detected."
return Image.open(buf), summary
def get_tab6_noise_simulation():
with gr.Tab("🔍 Eavesdropper Noise Simulation"):
original_input = gr.Textbox(label="Enter QKD Key (binary)", lines=3)
simulate_btn = gr.Button("Simulate Eavesdropping")
output_graph = gr.Image(label="Original vs Noisy Key")
summary_output = gr.Textbox(label="Noise Impact Summary", lines=2)
simulate_btn.click(
fn=compare_original_vs_noisy,
inputs=[original_input],
outputs=[output_graph, summary_output]
)