diff --git a/Rainbow.py b/Rainbow.py new file mode 100644 index 0000000..86876a7 --- /dev/null +++ b/Rainbow.py @@ -0,0 +1,246 @@ +from Crypto.Hash import MD4 +import threading +import random +import string +import queue +import Db + +lock = threading.Lock() + + +def md4(input_string): + # 将密码编码为 UTF-16LE + password_utf16 = input_string.encode('utf-16le') + + # 创建新的 MD4 哈希对象 + md4_hasher = MD4.new() + + # 更新 MD4 哈希对象 + md4_hasher.update(password_utf16) + + # 获取哈希值的十六进制表示 + ntlm_hash_hex = md4_hasher.hexdigest() + + return ntlm_hash_hex + + +class Rainbow_Cain: + def __init__(self, length, charset='abcdefghijklmnopqrstuvwxyz0123456789'): + self.length = length + self.charset = charset + self.db = Db.Db_Operation() + + def R1(self, hash_value): + reduced_value = '' + for i in range(self.length): + index = int(hash_value[i * 2:i * 2 + 2], 16) % len(self.charset) + reduced_value += self.charset[index] + return reduced_value + + def R2(self, hash_value): + reduced_value = '' + for i in range(self.length): + slice_start = (i * 3 + int(hash_value[i % len(hash_value)], 16)) % len(hash_value) + slice_end = (slice_start + 2) % len(hash_value) + if slice_end < slice_start: + slice_combined = hash_value[slice_start:] + hash_value[:slice_end] + else: + slice_combined = hash_value[slice_start:slice_end] + index = int(slice_combined, 16) % len(self.charset) + reduced_value += self.charset[index] + return reduced_value + + def R3(self, hash_value): + reduced_value = '' + for i in range(self.length): + slice_start = (i * 4 + int(hash_value[i * 2 % len(hash_value)], 16)) % len(hash_value) + slice_end = (slice_start + 3) % len(hash_value) + if slice_end < slice_start: + slice_combined = hash_value[slice_start:] + hash_value[:slice_end] + else: + slice_combined = hash_value[slice_start:slice_end] + index = int(slice_combined, 16) % len(self.charset) + reduced_value += self.charset[index] + return reduced_value + + def R4(self, hash_value): + reduced_value = '' + for i in range(self.length): + slice_start = (i * 5 + int(hash_value[i * 3 % len(hash_value)], 16)) % len(hash_value) + slice_end = (slice_start + 4) % len(hash_value) + if slice_end < slice_start: + slice_combined = hash_value[slice_start:] + hash_value[:slice_end] + else: + slice_combined = hash_value[slice_start:slice_end] + index = int(slice_combined, 16) % len(self.charset) + reduced_value += self.charset[index] + return reduced_value + + def R5(self, hash_value): + reduced_value = '' + for i in range(self.length): + slice_start = (i * 6 + int(hash_value[i * 4 % len(hash_value)], 16)) % len(hash_value) + slice_end = (slice_start + 5) % len(hash_value) + if slice_end < slice_start: + slice_combined = hash_value[slice_start:] + hash_value[:slice_end] + else: + slice_combined = hash_value[slice_start:slice_end] + index = int(slice_combined, 16) % len(self.charset) + reduced_value += self.charset[index] + return reduced_value + + def R6(self, hash_value): + reduced_value = '' + for i in range(self.length): + slice_start = (i * 7 + int(hash_value[i * 5 % len(hash_value)], 16)) % len(hash_value) + slice_end = (slice_start + 6) % len(hash_value) + if slice_end < slice_start: + slice_combined = hash_value[slice_start:] + hash_value[:slice_end] + else: + slice_combined = hash_value[slice_start:slice_end] + index = int(slice_combined, 16) % len(self.charset) + reduced_value += self.charset[index] + return reduced_value + + def R7(self, hash_value): + reduced_value = '' + for i in range(self.length): + slice_start = (i * 8 + int(hash_value[i * 6 % len(hash_value)], 16)) % len(hash_value) + slice_end = (slice_start + 7) % len(hash_value) + if slice_end < slice_start: + slice_combined = hash_value[slice_start:] + hash_value[:slice_end] + else: + slice_combined = hash_value[slice_start:slice_end] + index = int(slice_combined, 16) % len(self.charset) + reduced_value += self.charset[index] + return reduced_value + + def R8(self, hash_value): + reduced_value = '' + for i in range(self.length): + slice_start = (i * 9 + int(hash_value[i * 7 % len(hash_value)], 16)) % len(hash_value) + slice_end = (slice_start + 8) % len(hash_value) + if slice_end < slice_start: + slice_combined = hash_value[slice_start:] + hash_value[:slice_end] + else: + slice_combined = hash_value[slice_start:slice_end] + index = int(slice_combined, 16) % len(self.charset) + reduced_value += self.charset[index] + return reduced_value + + def R9(self, hash_value): + reduced_value = '' + for i in range(self.length): + slice_start = (i * 10 + int(hash_value[i * 8 % len(hash_value)], 16)) % len(hash_value) + slice_end = (slice_start + 9) % len(hash_value) + if slice_end < slice_start: + slice_combined = hash_value[slice_start:] + hash_value[:slice_end] + else: + slice_combined = hash_value[slice_start:slice_end] + index = int(slice_combined, 16) % len(self.charset) + reduced_value += self.charset[index] + return reduced_value + + def R10(self, hash_value): + reduced_value = '' + for i in range(self.length): + slice_start = (i * 11 + int(hash_value[i * 9 % len(hash_value)], 16)) % len(hash_value) + slice_end = (slice_start + 10) % len(hash_value) + if slice_end < slice_start: + slice_combined = hash_value[slice_start:] + hash_value[:slice_end] + else: + slice_combined = hash_value[slice_start:slice_end] + index = int(slice_combined, 16) % len(self.charset) + reduced_value += self.charset[index] + return reduced_value + + def Cain(self, random_str, K): + data_to_write = [] # 用于批量写入数据库的数据 + for i in range(K): + hashcode = md4(random_str) + r_str = self.R1(hashcode) + hashcode = md4(r_str) + r_str = self.R2(hashcode) + hashcode = md4(r_str) + r_str = self.R3(hashcode) + hashcode = md4(r_str) + r_str = self.R4(hashcode) + hashcode = md4(r_str) + r_str = self.R5(hashcode) + hashcode = md4(r_str) + r_str = self.R6(hashcode) + hashcode = md4(r_str) + r_str = self.R7(hashcode) + hashcode = md4(r_str) + r_str = self.R8(hashcode) + hashcode = md4(r_str) + r_str = self.R9(hashcode) + hashcode = md4(r_str) + r_str = self.R10(hashcode) + + data_to_write.append((random_str, r_str)) # 添加到批量写入列表 + random_str = r_str + # 批量写入数据库 + with lock: + self.db.write_to_database(data_to_write) + + +class Thread: + def __init__(self, desired_length, K, N, n): + self.desired_length = desired_length + self.rainbow_Cain = Rainbow_Cain(desired_length) + self.K = K + self.N = N + self.n = n + + def generate_random_string(self, charset=(string.ascii_letters + string.digits)): + """ + 生成指定位数的随机字符串 + :param charset: 字符集(可选),默认为字母和数字 + :return: 随机字符串 + """ + return ''.join(random.choice(charset) for _ in range(self.desired_length)) + + def thread_cain(self): + """ + 生成的数据为K*N条 + :desired_length: 解密长度 + :K: 轮数 + :N: 轮次 + """ + # 创建任务队列 + task_queue = queue.Queue() + + # 生成随机字符串列表 + input_strings = [self.generate_random_string(charset=string.ascii_lowercase) for _ in range(self.N)] + + # 将任务放入队列 + for input_string in input_strings: + task_queue.put(input_string) + + # 创建并启动线程 + threads = [] + for i in range(self.n): # 创建 n 个线程 + thread = threading.Thread(target=self.worker, args=(task_queue,)) + thread.start() + threads.append(thread) + + # 等待所有任务完成 + task_queue.join() + + # 等待所有线程结束 + for thread in threads: + thread.join() + + print("所有任务已完成!") + + def worker(self, task_queue): + # 每个线程创建独立的 Rainbow_Cain 实例 + rainbow_Cain = Rainbow_Cain(self.desired_length) + while not task_queue.empty(): + # 从队列中获取任务 + input_string = task_queue.get() + # 执行任务 + rainbow_Cain.Cain(input_string, self.K) + # 标记任务完成 + task_queue.task_done()