def crack3b(ciphertext): ciphertext = [text.strip() for text in ciphertext.split("|")] # parse the input orig_sentence = ciphertext[1] sentence = part2.sanitize_input(orig_sentence) key_length = int(ciphertext[0]) best_key = None best_score = None for seed in range(5): random.seed(seed) curr_key = tuple(random.randint(0, 26) for _ in range(key_length)) curr_key, key_score = simulated_annealing(score_key, get_neighbour_block_key, sentence, curr_key, 20) key, score = simulated_annealing(score_sentence, get_neighbour_block_key, sentence, curr_key, 0.1) if best_score is None or score > best_score: best_score = score best_key = key print("best score (annealing): {}".format(best_score)) # print("best score: {}".format(max(max(arr) for arr in arrays))) print("best key: {}".format(best_key)) print(part1.encryptBlock(sentence, list(best_key), False)) return " ".join([" ".join((str(k) for k in best_key)), "|", part1.encryptBlock(orig_sentence, best_key, False)])
def score_sentence(key, scores_dp, sentence): # if this score has already been calculated, just return it if key in scores_dp: return scores_dp[key] # else, calculate the score and return it dcr_sentence = part1.encryptBlock(sentence, key, False) # from part 1 return part2.get_ptb_sentence_score(dcr_sentence, ptb_prob_weights) # from part 2
def crack3a(ciphertext): bestScore = -inf bestText = None bestKey = -1 for i in range(0, 26): newText = part1.encryptBlock(ciphertext, [i], False) newScore = part2.get_ptb_sentence_score(part2.sanitize_input(newText), ptb_prob_weights) if newScore > bestScore: bestScore = newScore bestText = newText bestKey = i return str(bestKey) + " | " + bestText
def crack3c(orig_sentence): sentence = part2.sanitize_input(orig_sentence) best_key = None best_score = None for key_length in range(1, 8): for seed in range(3): random.seed(seed) curr_key = tuple(random.randint(0, 26) for _ in range(key_length)) curr_key, key_score = simulated_annealing(score_key, get_neighbour_block_key, sentence, curr_key, 20, MAX_STEPS / 3) key, score = simulated_annealing(score_sentence, get_neighbour_block_key, sentence, curr_key, 0.1, MAX_STEPS / 3) if best_score is None or score > best_score: best_score = score best_key = key print("best score (annealing): {}".format(best_score)) # print("best score: {}".format(max(max(arr) for arr in arrays))) print("best key: {}".format(best_key)) print(part1.encryptBlock(sentence, list(best_key), False)) return " ".join([" ".join((str(k) for k in best_key)), "|", part1.encryptBlock(orig_sentence, best_key, False)])
def simulated_annealing(get_score, get_neighbour, sentence, curr_key, score_scale, max_steps=MAX_STEPS): temperature = MAX_TEMPERATURE # track score over time scores_dp = OrderedDict() # keep the best resolution for printing at the end best_score = get_score(curr_key, scores_dp, sentence) best_key = curr_key best_decrypt = part1.encryptBlock(sentence, list(best_key), False) step = 0 while step < max_steps: # score current state (only care about maximum per location) curr_score = get_score(curr_key, scores_dp, sentence) # track score scores_dp[curr_key] = curr_score # print(temperature, curr_score) # pick random neighbour new_key = get_neighbour(curr_key, isStateValid) new_score = get_score(new_key, scores_dp, sentence) # export for visualization # print("{}|{}|{}".format(time.time(), best_score, best_decrypt), file=VISUALIZATION_FILE) if pick_state(curr_score, new_score, temperature, MAX_TEMPERATURE, BASE_SELECTIVITY, score_scale) > random.random(): curr_key = new_key if new_score > best_score: best_score = new_score best_key = new_key # print("step {} \tbest {}".format(step, best_score)) temperature = anneal(temperature, step) step += 1 return best_key, best_score