+ "execution_count": 39,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "beaufort_decipher('sevsvrusyrrxfayyxuteemazudmpjmmwr', 'arcanaimperii')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 40,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# def beaufort_sub_break(message, fitness=Pletters):\n",
+ "# best_shift = 0\n",
+ "# best_fit = float('-inf')\n",
+ "# for key in range(26):\n",
+ "# plaintext = [unpos(key - pos(l)) for l in message]\n",
+ "# fit = fitness(plaintext)\n",
+ "# logger.debug('Beaufort sub break attempt using key {0} gives fit of {1} '\n",
+ "# 'and decrypt starting: {2}'.format(key, fit,\n",
+ "# plaintext[:50]))\n",
+ "# if fit > best_fit:\n",
+ "# best_fit = fit\n",
+ "# best_key = key\n",
+ "# logger.info('Beaufort sub break best fit: key {0} gives fit of {1} and '\n",
+ "# 'decrypt starting: {2}'.format(best_key, best_fit, \n",
+ "# cat([unpos(best_key - pos(l)) for l in message[:50]])))\n",
+ "# return best_key, best_fit"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 41,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# def beaufort_frequency_break(message, max_key_length=20, fitness=Pletters):\n",
+ "# \"\"\"Breaks a Beaufort cipher with frequency analysis\n",
+ "\n",
+ "# >>> beaufort_frequency_break(beaufort_encipher(sanitise(\"It is time to \" \\\n",
+ "# \"run. She is ready and so am I. I stole Daniel's pocketbook this \" \\\n",
+ "# \"afternoon when he left his jacket hanging on the easel in the \" \\\n",
+ "# \"attic. I jump every time I hear a footstep on the stairs, \" \\\n",
+ "# \"certain that the theft has been discovered and that I will \" \\\n",
+ "# \"be caught. The SS officer visits less often now \" \\\n",
+ "# \"that he is sure\"), 'florence')) # doctest: +ELLIPSIS\n",
+ "# ('florence', -307.5473096791...)\n",
+ "# \"\"\"\n",
+ "# def worker(message, key_length, fitness):\n",
+ "# splits = every_nth(message, key_length)\n",
+ "# key = cat([unpos(beaufort_sub_break(s)[0]) for s in splits])\n",
+ "# plaintext = beaufort_decipher(message, key)\n",
+ "# fit = fitness(plaintext)\n",
+ "# return key, fit\n",
+ "# sanitised_message = sanitise(message)\n",
+ "# results = starmap(worker, [(sanitised_message, i, fitness)\n",
+ "# for i in range(1, max_key_length+1)])\n",
+ "# return max(results, key=lambda k: k[1])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 42,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "('arcanaimperii', -1506.8637359274674)"
+ ]
+ },
+ "execution_count": 42,