Flipper/Sub-GHz/OOK_bruteforce/flipperzero-bruteforce.py
2022-08-03 13:25:42 -07:00

113 lines
3.8 KiB
Python

import os
# Script settings:
REPETITION = 4 # number of tx per key
# Protocol settings: https://phreakerclub.com/447
class Protocol:
def __init__(
self, name, n_bits, transposition_table, pilot_period=None, frequency=433920000
):
self.name = name
self.n_bits = n_bits
self.transposition_table = transposition_table
self.pilot_period = pilot_period
self.file_header = (
"Filetype: Flipper SubGhz RAW File\n"
+ "Version: 1\n"
+ f"Frequency: {frequency}\n"
+ "Preset: FuriHalSubGhzPresetOok650Async\n"
+ "Protocol: RAW\n"
)
def key_dec_to_str(self, key_dec):
key_bin = f"{key_dec:012b}" # format as 12 digits bin
return self.key_bin_to_str(key_bin)
def key_bin_to_str(self, key_bin):
key_str = self.pilot_period if self.pilot_period else ""
line_len = 0 # keep lines under 2500 chars
for bit in key_bin:
if line_len > 2500:
key_str += "\nRAW_Data: "
line_len = 0
key_str += self.transposition_table[bit]
line_len += len(self.transposition_table[bit])
return key_str
def de_bruijn(self):
"""
de Bruijn binary sequence
credit: https://www.rosettacode.org/wiki/De_Bruijn_sequences#Python
"""
alphabet = "01"
k = 2
a = [0] * k * self.n_bits
sequence = []
def db(t, p):
if t > self.n_bits:
if self.n_bits % p == 0:
sequence.extend(a[1 : p + 1])
else:
a[t] = a[t - p]
db(t + 1, p)
for j in range(a[t - p] + 1, k):
a[t] = j
db(t + 1, t)
db(1, 1)
db_seq = "".join(alphabet[i] for i in sequence)
return self.key_bin_to_str(db_seq)
def generate_sub_files(self):
"""
Generate sub files grouped by split nuber of keys
Directory structure:
- sub_files
- protocol_name
- split_factor
- split_factor_id.sub
"""
base_dir = f"sub_files/{self.name}"
os.makedirs(base_dir, exist_ok=True)
# Create debruijn.sub
filename = f"{base_dir}/debruijn.sub"
with open(filename, "w") as f:
f.write(self.file_header)
with open(filename, "a") as f:
f.write("RAW_Data: " + self.de_bruijn() + "\n")
if self.n_bits > 12: # take up too much space, try de bruijn instead
return
# Generate sets of 1, 2, 4, 8, 16, 32 .sub files
splits = [int(pow(2, self.n_bits) / _) for _ in [pow(2, _) for _ in range(6)]]
for split in splits:
split_dir = f"{base_dir}/{split}"
os.makedirs(split_dir, exist_ok=True)
for key_dec in range(pow(2, self.n_bits)):
key_str = self.key_dec_to_str(key_dec) * REPETITION
if (key_dec % split) == 0:
filename = f"{split_dir}/{key_dec / split:03.0f}.sub"
with open(filename, "w") as f:
f.write(self.file_header)
with open(filename, "a") as f:
f.write("RAW_Data: " + key_str + "\n")
protocols = [
Protocol("CAME", 12, {"0": "-320 640 ", "1": "-640 320 "}, "-11520 320 "),
Protocol("NICE", 12, {"0": "-700 1400 ", "1": "-1400 700 "}, "-25200 700 "),
# 24 bits take up too much space to upload to github as over 100MB
Protocol("PT-2240", 24, {"0": "450 -1350 ", "1": "1350 -450 "}, "450 -13950 "),
Protocol("PT-2262", 24, {"0": "450 -1350 ", "1": "1350 -450 "}, "450 -13950 "),
Protocol("8bit", 8, {"0": "200 -400 ", "1": "400 -200 "}), # generic 8 bit protocol
]
for p in protocols:
p.generate_sub_files()
print(f"{p.name} done")