import hashlib
import random
import time
# Configuration
TOTAL_SIZE = 100_000
RANGE_SIZE = 5_000
PREFIX_LENGTH = 3
SIMULATIONS = 500
SECP256K1_ORDER = int("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16)
print(f"""
=== Configuration ===
Total numbers: {TOTAL_SIZE:,}
Block size: {RANGE_SIZE:,}
Prefix: {PREFIX_LENGTH} characters (16^{PREFIX_LENGTH} combinations)
Simulations: {SIMULATIONS}
secp256k1 Order: {SECP256K1_ORDER}
""")
def generate_h160(data):
h = hashlib.new('ripemd160', str(data).encode('utf-8'))
return h.hexdigest()
def shuffled_range(n):
arr = list(range(n + 1))
random.shuffle(arr)
return arr
def Scooby_Doo(dataset, block, target_hash, order):
checks = 0
ranges = []
for idx in order:
start = idx * block
end = start + block
marked = False
for i in range(start, end):
checks += 1
h = generate_h160(dataset[i])
if h == target_hash:
return {"checks": checks, "found": True}
if not marked and random.randint(0, 5000) == 0: # ktimesg randomness
marked = True
ranges.append({"start": i + 1, "end": end})
break
for r in ranges:
for i in range(r["end"] - 1, r["start"] - 1, -1):
checks += 1
if generate_h160(dataset[i]) == target_hash:
return {"checks": checks, "found": True}
return {"checks": checks, "found": False}
def prefixes_search(dataset, block, prefix, target_hash, order):
prefix_hash = target_hash[:prefix]
checks = 0
ranges = []
for idx in order:
start = idx * block
end = start + block
found_prefix = False
for i in range(start, end):
checks += 1
h = generate_h160(dataset[i])
if h == target_hash:
return {"checks": checks, "found": True}
if not found_prefix and h.startswith(prefix_hash):
found_prefix = True
ranges.append({"start": i + 1, "end": end})
break
for r in ranges:
for i in range(r["end"] - 1, r["start"] - 1, -1):
checks += 1
if generate_h160(dataset[i]) == target_hash:
return {"checks": checks, "found": True}
return {"checks": checks, "found": False}
def compare_methods():
results = {
"Scooby_Doo": {"wins": 0, "total_checks": 0, "total_time": 0},
"prefixes": {"wins": 0, "total_checks": 0, "total_time": 0},
"ties": 0
}
for i in range(SIMULATIONS):
max_range = SECP256K1_ORDER - TOTAL_SIZE - 1
random_offset = random.randrange(max_range)
R = 1 + random_offset
dataset = [R + i for i in range(TOTAL_SIZE)]
target_num = random.choice(dataset)
target_hash = generate_h160(target_num)
blocks = TOTAL_SIZE // RANGE_SIZE
order = shuffled_range(blocks - 1)
start_time = time.perf_counter()
seq_result = Scooby_Doo(dataset, RANGE_SIZE, target_hash, order)
end_time = time.perf_counter()
seq_time = end_time - start_time
start_time = time.perf_counter()
pre_result = prefixes_search(dataset, RANGE_SIZE, PREFIX_LENGTH, target_hash, order)
end_time = time.perf_counter()
pre_time = end_time - start_time
results["Scooby_Doo"]["total_checks"] += seq_result["checks"]
results["prefixes"]["total_checks"] += pre_result["checks"]
results["Scooby_Doo"]["total_time"] += seq_time
results["prefixes"]["total_time"] += pre_time
if seq_result["checks"] < pre_result["checks"]:
results["Scooby_Doo"]["wins"] += 1
elif seq_result["checks"] > pre_result["checks"]:
results["prefixes"]["wins"] += 1
else:
results["ties"] += 1
print(f"Simulation {i + 1}: Scooby_Doo = {seq_result['checks']} checks in {seq_time:.6f}s | Prefix = {pre_result['checks']} checks in {pre_time:.6f}s")
avg_success_rate_Scooby_Doo = (results["Scooby_Doo"]["total_checks"] / results["Scooby_Doo"]["wins"]
if results["Scooby_Doo"]["wins"] > 0 else float('inf'))
avg_success_rate_prefixes = (results["prefixes"]["total_checks"] / results["prefixes"]["wins"]
if results["prefixes"]["wins"] > 0 else float('inf'))
avg_time_Scooby_Doo = (results["Scooby_Doo"]["total_time"] / results["Scooby_Doo"]["wins"]
if results["Scooby_Doo"]["wins"] > 0 else float('inf'))
avg_time_prefixes = (results["prefixes"]["total_time"] / results["prefixes"]["wins"]
if results["prefixes"]["wins"] > 0 else float('inf'))
print(f"""
=== FINAL RESULTS ===
Wins:
Scooby_Doo: {results['Scooby_Doo']['wins']}
Prefix: {results['prefixes']['wins']}
Ties: {results['ties']}
Total Checks:
Scooby_Doo: {results['Scooby_Doo']['total_checks']}
Prefix: {results['prefixes']['total_checks']}
Total Time:
Scooby_Doo: {results['Scooby_Doo']['total_time']:.6f} seconds
Prefix: {results['prefixes']['total_time']:.6f} seconds
Averages (Total Time / Wins):
Scooby_Doo : {avg_time_Scooby_Doo:.6f} seconds/victory
Prefix : {avg_time_prefixes:.6f} seconds/victory
Checks per Win:
Scooby_Doo : {avg_success_rate_Scooby_Doo:.2f} checks/win
Prefix : {avg_success_rate_prefixes:.2f} checks/win
""")
if __name__ == '__main__':
compare_methods()
=== FINAL RESULTS ===
Wins:
Scooby_Doo: 228
Prefix: 260
Ties: 12
Total Checks:
Scooby_Doo: 24851576
Prefix: 25623847
Total Time:
Scooby_Doo: 342.907286 seconds
Prefix: 280.652503 seconds
Averages (Total Time / Wins):
Scooby_Doo : 1.503979 seconds/victory
Prefix : 1.079433 seconds/victory
Checks per Win:
Scooby_Doo : 108998.14 checks/win
Prefix : 98553.26 checks/win
=== FINAL RESULTS ===
Wins:
Scooby_Doo: 225
Prefix: 263
Ties: 12
Total Checks:
Scooby_Doo: 24624530
Prefix: 25240078
Total Time:
Scooby_Doo: 340.911049 seconds
Prefix: 278.872279 seconds
Averages (Total Time / Wins):
Scooby_Doo : 1.515160 seconds/victory
Prefix : 1.060351 seconds/victory
Checks per Win:
Scooby_Doo : 109442.36 checks/win
Prefix : 95969.88 checks/win
=== FINAL RESULTS ===
Wins:
Scooby_Doo: 229
Prefix: 265
Ties: 6
Total Checks:
Scooby_Doo: 24905305
Prefix: 24688332
Total Time:
Scooby_Doo: 348.265537 seconds
Prefix: 263.037687 seconds
Averages (Total Time / Wins):
Scooby_Doo : 1.520810 seconds/victory
Prefix : 0.992595 seconds/victory
Checks per Win:
Scooby_Doo : 108756.79 checks/win
Prefix : 93163.52 checks/win
=== FINAL RESULTS ===
Wins:
Scooby_Doo: 222
Prefix: 267
Ties: 11
Total Checks:
Scooby_Doo: 25225653
Prefix: 25081620
Total Time:
Scooby_Doo: 335.807665 seconds
Prefix: 260.804346 seconds
Averages (Total Time / Wins):
Scooby_Doo : 1.512647 seconds/victory
Prefix : 0.976795 seconds/victory
Checks per Win:
Scooby_Doo : 113629.07 checks/win
Prefix : 93938.65 checks/win