Skip to content

Instantly share code, notes, and snippets.

@LucianoHanna
Created January 7, 2026 11:52
Show Gist options
  • Select an option

  • Save LucianoHanna/e95bce09c0e2dd5eeb529cc7aa745d28 to your computer and use it in GitHub Desktop.

Select an option

Save LucianoHanna/e95bce09c0e2dd5eeb529cc7aa745d28 to your computer and use it in GitHub Desktop.
import random
import statistics
import time
def realizar_simulacao(num_simulacoes=100, espaco_amostral=1000000, tamanho_conjunto_ataque=5):
"""
Simulates the reverse brute force attack on OTP.
Args:
num_simulacoes: How many times the attack will be successful to generate statistics.
espaco_amostral: 6 digits = 1,000,000 possibilities (000000 to 999999).
tamanho_conjunto_ataque: How many guesses the attacker sends (limit of attempts per OTP).
"""
# The attacker defines their 5 "lucky" codes (ex: 000000, 111111, etc.)
# Mathematically, which numbers they are doesn't matter, only the quantity.
# We use a set for O(1) lookup
conjunto_ataque = set(random.sample(range(espaco_amostral), tamanho_conjunto_ataque))
resultados = []
print(f"--- Starting Simulation ---")
print(f"Sample Space: {espaco_amostral} (6 digits)")
print(f"Attacker Attempts (Simultaneous): {tamanho_conjunto_ataque}")
print(f"Simulations to run: {num_simulacoes}")
print("Processing...", end="", flush=True)
start_time = time.time()
for i in range(num_simulacoes):
geracoes_necessarias = 0
encontrou = False
while not encontrou:
geracoes_necessarias += 1
# The Server generates a random OTP
otp_gerado = random.randint(0, espaco_amostral - 1)
# We check if the generated OTP falls into the attacker's set of guesses
if otp_gerado in conjunto_ataque:
encontrou = True
resultados.append(geracoes_necessarias)
# Simple visual feedback every 10% of progress
if (i + 1) % (num_simulacoes // 10) == 0:
print(".", end="", flush=True)
end_time = time.time()
print("\n--- End of Simulation ---\n")
# Statistical Calculations
media = statistics.mean(resultados)
mediana_p50 = statistics.median(resultados)
# Quantiles for P90 and P95
# (Requires Python 3.8+. If error occurs, use numpy or simple manual calculation)
quantis = statistics.quantiles(resultados, n=100)
p90 = quantis[89] # 90th percentile
p95 = quantis[94] # 95th percentile
print(f"Execution time: {end_time - start_time:.4f} seconds")
print(f"Total successes simulated: {num_simulacoes}")
print("-" * 30)
print(f"Average generations needed: {media:,.2f}")
print(f"P50 (Median): {mediana_p50:,.2f}")
print(f"P90 (90% of cases): {p90:,.2f}")
print(f"P95 (95% of cases): {p95:,.2f}")
print("-" * 30)
# Theoretical Validation
probabilidade = tamanho_conjunto_ataque / espaco_amostral
expectativa_teorica = 1 / probabilidade
print(f"Theoretical Expectation (1/p): {expectativa_teorica:,.2f}")
if __name__ == "__main__":
# Running 100 simulations to get a quick statistical sample
# Increase to 1000+ for higher precision (will take more time)
realizar_simulacao(num_simulacoes=10000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment