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")