Skip to content

Instantly share code, notes, and snippets.

@kvedala
Last active May 15, 2020 00:51
Show Gist options
  • Save kvedala/97a39a04437a1724a17aabfbe6bed39a to your computer and use it in GitHub Desktop.
Save kvedala/97a39a04437a1724a17aabfbe6bed39a to your computer and use it in GitHub Desktop.
Hill Cypher - Python and Cython
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.4"
},
"colab": {
"name": "Hill Cypher - Python and Cython",
"provenance": [],
"collapsed_sections": [],
"include_colab_link": true
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/kvedala/97a39a04437a1724a17aabfbe6bed39a/notebook.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "code",
"metadata": {
"id": "b0Buis-s4wKw",
"colab_type": "code",
"colab": {}
},
"source": [
"!pip -qq install line_profiler\n",
"import random, os, numba\n",
"import numpy as np\n",
"from scipy import linalg\n",
"%reload_ext cython\n",
"%reload_ext line_profiler\n",
"rand = np.random.default_rng()"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "iklHgF5d4wLf",
"colab_type": "code",
"colab": {}
},
"source": [
"@numba.jit(\"int64(int64,int64)\", nopython=True)\n",
"def gcd_n(a: int, b: int)->int:\n",
" if a < 0 or b < 0:\n",
" return -1\n",
" while b != 0:\n",
" a, b = b, a % b\n",
" return a\n",
"\n",
"@numba.jit(\"boolean(int64)\", nopython=True)\n",
"def is_even_n(a: int)->bool:\n",
" if a & 1 == 1:\n",
" return False\n",
" else:\n",
" return True\n",
"\n",
"@numba.jit(\"int64(int64,int64)\", nopython=True)\n",
"def gcd_n2(a: int, b: int)->int:\n",
" if a == b:\n",
" return a\n",
" if a == 0 and b != 0:\n",
" return b\n",
" if a != 0 and b == 0:\n",
" return a\n",
" if a == 0 and b == 0:\n",
" return 0\n",
" a_even = is_even_n(a)\n",
" b_even = is_even_n(b)\n",
" if a_even and b_even:\n",
" return gcd_n2(a >> 1, b >> 1) << 1\n",
" if a_even:\n",
" return gcd_n2(a >> 1, b)\n",
" if b_even:\n",
" return gcd_n2(a, b >> 1)\n",
" if a >= b:\n",
" return gcd_n2((a - b) >> 1, b)\n",
" else:\n",
" return gcd_n2((b - a) >> 1, a)\n",
" \n",
"\n",
"@numba.jit\n",
"def extended_gcd_n(a: int, b: int):\n",
" s = 0;\n",
" old_s = 1\n",
" r = b \n",
" old_r = a\n",
" \n",
" while r != 0:\n",
" quotient = old_r // r\n",
" old_r, r = r, old_r - quotient * r\n",
" old_s, s = s, old_s - quotient * s\n",
" \n",
" if b != 0:\n",
" bezout_t = (old_r - old_s * a) // b;\n",
" else:\n",
" bezout_t = 0\n",
" \n",
" return (old_s, bezout_t), old_r\n",
"# output \"Bézout coefficients:\", (old_s, bezout_t)\n",
"# output \"greatest common divisor:\", old_r\n",
"\n",
"\n",
"@numba.jit(forceobj=True, nopython=True, locals={'dd': \"int64\", \"gcd\":'int', \"min_det\":'int64'})\n",
"def get_matrix(min_int=0, max_int=100, MAX_TRIES=1e5, MAX_DET=1<<40, size=10):\n",
" tries = 0\n",
" modulus = 97\n",
" size = (size,size)\n",
" dd = -1\n",
" a = min_a = rand.integers(min_int, max_int, size=size, dtype=np.int16)\n",
" dd = dd2 = int(linalg.det(a % modulus))\n",
" if dd < 0:\n",
" dd = dd % modulus\n",
" min_det = dd\n",
" gcd = gcd_n(dd, modulus)\n",
" min_gcd = gcd\n",
"# while (det < 0 or det > MAX_DET) and tries < MAX_TRIES:\n",
" while tries < MAX_TRIES and abs(dd2) > MAX_DET:\n",
" a = np.random.randint(min_int, max_int, size=size, dtype=np.int16)\n",
"# det = linalg.det(a)\n",
" dd = dd2 = int(linalg.det(a % modulus))\n",
" if dd < 0:\n",
" dd = dd % modulus\n",
" tries += 1\n",
" gcd = gcd_n(dd, modulus)\n",
" if dd < min_det and dd > 1 and gcd == 1:\n",
" min_det = dd\n",
" min_a = a\n",
" min_gcd = gcd\n",
" if min_det >= MAX_DET:\n",
" print(\"Unable to find a solution.\")\n",
" \n",
" return tries, min_det, min_gcd, min_a.astype(np.int32)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "qZ_72MaO4wLr",
"colab_type": "code",
"outputId": "49970dd2-7f5c-406b-b4ba-87a2ca643a84",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 238
}
},
"source": [
"max_det = 1<<50\n",
"%time tries, det, gcd, a = get_matrix(0, 30, 1e5, max_det, 10)\n",
"print(\"{} \\t {:g}\\t {:g} <> {:g}\\t gcd: {}\\n {}\".format(tries, np.linalg.det(a), det, max_det, gcd, a))"
],
"execution_count": 10,
"outputs": [
{
"output_type": "stream",
"text": [
"CPU times: user 259 µs, sys: 22 µs, total: 281 µs\n",
"Wall time: 288 µs\n",
"0 \t 1.5218e+12\t 1.5218e+12 <> 1.1259e+15\t gcd: 1\n",
" [[22 5 24 8 12 6 22 11 27 22]\n",
" [ 9 19 3 29 15 1 10 25 13 1]\n",
" [13 11 6 6 1 7 27 7 4 28]\n",
" [22 13 27 5 19 20 29 17 21 12]\n",
" [27 11 0 19 3 19 20 28 24 18]\n",
" [ 6 22 16 2 8 21 25 10 24 29]\n",
" [12 22 9 10 2 29 15 0 25 24]\n",
" [ 7 14 0 5 13 25 29 17 17 2]\n",
" [ 9 22 11 13 20 18 4 16 21 29]\n",
" [ 1 21 11 3 22 19 23 12 10 20]]\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "IXRMVKhQ4wL3",
"colab_type": "code",
"outputId": "53ec1d40-1cef-4086-b7d0-5c998fa9d7f2",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 153
}
},
"source": [
"%%cython --link-args=-fopenmp\n",
"# cython: boundscheck=False\n",
"# cython: wraparound=False\n",
"# cython: nonecheck=False\n",
"# cython: cdivision=True\n",
"# cython: profile=True\n",
"# cython: linetrace=True\n",
"# cython: binding=True\n",
"# cython: language_level=3\n",
"# distutils: define_macros=CYTHON_TRACE_NOGIL=1\n",
"# distutils: extra_compile_args=-fopenmp -Wall -Ofast\n",
"# cython: c_string_encoding=ascii\n",
"#--# distutils: language=c++\n",
"\n",
"print(\"size of int = {:2d} bytes = {:3d} bits\".format(sizeof(int), sizeof(int)<<3))\n",
"print(\"size of long = {:2d} bytes = {:3d} bits\".format(sizeof(long), sizeof(long)<<3))\n",
"print(\"size of long long = {:2d} bytes = {:3d} bits\".format(sizeof(long long), sizeof(long long)<<3))\n",
"print(\"size of float = {:2d} bytes = {:3d} bits\".format(sizeof(float), sizeof(float)<<3))\n",
"print(\"size of double = {:2d} bytes = {:3d} bits\".format(sizeof(double), sizeof(double)<<3))\n",
"print(\"size of long double = {:2d} bytes = {:3d} bits\".format(sizeof(long double), sizeof(long double)<<3))\n",
"\n",
"cimport cython\n",
"from cython.parallel cimport prange\n",
"cimport numpy as np\n",
"import numpy as np\n",
"\n",
"from libc.math cimport round\n",
"from libc.stdio cimport printf\n",
"from libc.stdlib cimport rand, abort\n",
"from libc.string cimport strlen, strcpy, memset, memcpy\n",
"cdef extern from \"stdlib.h\":\n",
" double RAND_MAX\n",
"from cpython.mem cimport PyMem_RawMalloc, PyMem_RawRealloc, PyMem_RawFree\n",
"\n",
"cdef const char *STRKEY = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&*()_+`-=[]\\{}|;':\\\",./<>?\\r\\n \"\n",
"# cdef const char *STRKEY = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n",
"print(\"Key string: %s\\nKey length: %d\" %(STRKEY, strlen(STRKEY)))\n",
"\n",
"cdef np.int64_t randrange(np.int64_t a, np.int64_t b) nogil:\n",
" cdef long double r = <long double> rand() / RAND_MAX\n",
" r = r * (b - a) + a \n",
" return <np.int64_t> r\n",
"\n",
"\n",
"cdef np.int64_t gcd(np.int64_t a, np.int64_t b) nogil:\n",
" if b > a: # make sure that a > b\n",
" a, b = b, a\n",
" \n",
" while b != 0:\n",
" a, b = b, a % b\n",
" return a\n",
"\n",
"\n",
"def gcd_c(np.int64_t a, np.int64_t b)->int:\n",
" return gcd(a, b)\n",
"\n",
"\n",
"cdef class HillCipher(object):\n",
" cdef:\n",
" char *key_string\n",
" public np.int32_t[:,:] encrypt_key\n",
" public np.int32_t[:,:] decrypt_key\n",
" int key_len, break_key\n",
" np.int64_t det\n",
"# char *__tmp\n",
" \n",
"# def __dealloc__(self):\n",
"# if self.__tmp is not NULL:\n",
"# PyMem_RawFree(self.__tmp)\n",
" \n",
" \n",
" def __cinit__(self):\n",
" \"\"\"\n",
" encrypt_key is an NxN numpy matrix\n",
" \"\"\"\n",
" self.key_string = STRKEY\n",
"# self.__tmp = <char*> PyMem_RawMalloc(1)\n",
"# if self.__tmp is NULL:\n",
"# raise MemoryError(\"init: Unable to allocate single byte memory.\")\n",
"\n",
" \n",
" def __init__(self, np.ndarray[np.int32_t,ndim=2] encrypt_key):\n",
" \"\"\"\n",
" encrypt_key is an NxN numpy matrix\n",
" \"\"\"\n",
" cdef np.int64_t det_gcd\n",
" self.key_len = strlen(STRKEY)\n",
" self.break_key = encrypt_key.shape[0]\n",
" self.encrypt_key = encrypt_key % self.key_len\n",
" self.check_determinant(&det_gcd)\n",
" if det_gcd != 1:\n",
" raise ValueError(\"discriminant modular {} of encryption key({}) is not co prime w.r.t {}.\\nTry another key.\".format(\n",
" self.key_len, self.det, self.key_len))\n",
" self.decrypt_key = encrypt_key.copy()\n",
" self.make_decrypt_key()\n",
" \n",
" \n",
" cdef inline np.uint64_t modulo(self, np.int64_t N) nogil:\n",
" cdef np.int64_t ret = N % self.key_len\n",
" if ret >= 0:\n",
" return ret \n",
" else:\n",
" return ret + self.key_len\n",
" \n",
" \n",
" cdef void check_determinant(self, np.int64_t *r_gcd):\n",
" cdef long tmp\n",
" self.det = <np.int64_t> round(np.linalg.det(self.encrypt_key))\n",
"\n",
" with nogil:\n",
" tmp = self.modulo(self.det) if self.det < 0 else self.det\n",
" r_gcd[0] = gcd(tmp, self.key_len)\n",
"\n",
"# printf(\"det: %ld\\t tmp: %ld\\t key_len: %ld\\t gcd: %ld\\n\", self.det, tmp, self.key_len, r_gcd[0])\n",
" \n",
"\n",
" cdef void process_text(self, const np.uint8_t[:] in_text, np.uint8_t *out_text):\n",
" cdef:\n",
" long L = in_text.shape[0] # strlen(text)\n",
" int M = self.encrypt_key.shape[0]\n",
" long L2 = L if L % M == 0 else L + M - (L % M)\n",
" long i\n",
" np.uint8_t last = in_text[L-1]\n",
" \n",
" with nogil:\n",
" strcpy(<char*> out_text, <const char*> &in_text[0])\n",
" for i in range(L, L2):\n",
" out_text[i] = last\n",
"\n",
"# out_text[L2] = b'\\0' # for C-compatibility\n",
" \n",
"\n",
" cdef inline np.uint8_t get_char_index(self, const char ch) nogil:\n",
" cdef np.uint8_t idx\n",
" for idx in range(self.key_len):\n",
" if self.key_string[idx] == ch:\n",
" return idx\n",
" raise ValueError(\"Should not be seeing this! Probably non-alphanumeric character present: '{}'\".format(ch))\n",
"\n",
" \n",
" cdef inline char get_index_char(self, const np.uint8_t idx) nogil:\n",
" return self.key_string[idx]\n",
"\n",
" \n",
" cdef void mat_mul(self, const np.uint8_t[:] vec, np.uint8_t[:] out, np.uint8_t to_encode):\n",
" cdef:\n",
" int i, j\n",
" np.int64_t tmp\n",
" if to_encode > 1:\n",
" raise ValueError(\"'to_encode={}' should be 0 or 1\".format(to_encode))\n",
" \n",
" for i in range(self.break_key):\n",
" tmp = 0\n",
" for j in range(self.break_key):\n",
" if to_encode == 0:\n",
" tmp += self.encrypt_key[i,j] * vec[j]\n",
" elif to_encode == 1:\n",
" tmp += self.decrypt_key[i,j] * vec[j]\n",
" out[i] = <np.uint8_t> (tmp % self.key_len)\n",
" \n",
" \n",
" cpdef str codec(self, const np.uint8_t[:] text, np.int8_t type=1):\n",
" cdef:\n",
" long L = text.shape[0] # strlen(text)\n",
" int M = self.break_key\n",
" long L2 = L if L % M == 0 else L + M - (L % M)\n",
" int i, j\n",
" np.uint8_t *_tmp = <np.uint8_t*> PyMem_RawMalloc(L2)\n",
" np.ndarray[ndim=1,dtype=np.uint8_t] _batch_int = np.ndarray(self.break_key, dtype=np.uint8)\n",
" np.uint8_t[:] batch_int = _batch_int\n",
" np.ndarray[ndim=1,dtype=np.uint8_t] batch_encrypt = np.ndarray(self.break_key, dtype=np.uint8)\n",
" np.uint8_t[:] _batch_encrypt = batch_encrypt\n",
" char *encrypted_txt = <char*> PyMem_RawMalloc(L2)\n",
" np.uint8_t *tmp2\n",
" \n",
" if _tmp is NULL or encrypted_txt is NULL:\n",
" raise MemoryError(\"encrypt: Unable to allocate memory.\")\n",
" \n",
" memset(encrypted_txt, b'\\0', L2)\n",
" \n",
" try:\n",
" self.process_text(text, _tmp)\n",
" for i in range(0, L2 - self.break_key + 1, self.break_key):\n",
" for j in range(self.break_key):\n",
" batch_int[j] = self.get_char_index(_tmp[i + j])\n",
" \n",
" self.mat_mul(batch_int, _batch_encrypt, type)\n",
" for j in range(self.break_key):\n",
" encrypted_txt[i+j] = self.get_index_char(_batch_encrypt[j])\n",
" \n",
"# print(\"batch: {}: {}: {}: {}: {}\".format(\n",
"# [chr(_tmp[i+c]) for c in range(self.break_key)], \n",
"# list(batch_int),\n",
"# [chr(self.get_index_char(c)) for c in batch_int],\n",
"# list(batch_encrypt),\n",
"# [chr(self.get_index_char(c)) for c in batch_encrypt],\n",
"# ))\n",
" \n",
" encrypted_txt[L2] = b'\\0'\n",
"# printf(\"%s\\n\", encrypted_txt)\n",
" return <str> encrypted_txt\n",
" finally:\n",
" PyMem_RawFree(_tmp)\n",
" PyMem_RawFree(encrypted_txt)\n",
" \n",
" \n",
" cdef void make_decrypt_key(self):\n",
" cdef np.int8_t i, j, det_inv = -1\n",
" cdef np.int64_t tmp_val\n",
" cdef long det_tmp = self.det % self.key_len if self.det < 0 else self.det\n",
" cdef double[:,:] tmp = np.linalg.inv(self.encrypt_key)\n",
" \n",
" for i in range(self.key_len):\n",
" if self.modulo(det_tmp * i) == 1:\n",
" det_inv = i\n",
" break\n",
" \n",
" if det_inv == -1:\n",
" raise ValueError(\"could not find a co-prime for inversion\")\n",
" \n",
" det_tmp = det_inv * self.det\n",
" \n",
" for i in range(self.break_key):\n",
" for j in range(self.break_key):\n",
" tmp_val = <np.int64_t> round(tmp[i,j] * det_tmp)\n",
" self.decrypt_key[i,j] = self.modulo(tmp_val)\n",
" \n",
"\n",
"def blank(self):\n",
" pass"
],
"execution_count": 11,
"outputs": [
{
"output_type": "stream",
"text": [
"size of int = 4 bytes = 32 bits\n",
"size of long = 8 bytes = 64 bits\n",
"size of long long = 8 bytes = 64 bits\n",
"size of float = 4 bytes = 32 bits\n",
"size of double = 8 bytes = 64 bits\n",
"size of long double = 16 bytes = 128 bits\n",
"Key string: b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&*()_+`-=[]\\\\{}|;\\':\",./<>?\\r\\n '\n",
"Key length: 97\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "arIDUKnb4wMI",
"colab_type": "code",
"outputId": "3bce0f3b-85da-40c0-b0a3-02b8aea2765c",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 561
}
},
"source": [
"# %time %time tries, det, a = get_matrix(0, 150, 1e5, max_det, 9)\n",
"print(a)\n",
"if 'h' in locals():\n",
" del h\n",
"# %lprun -f HillCipher.make_decrypt_key h = HillCipher(a)\n",
"%time h = HillCipher(a)\n",
"print(np.asarray(h.encrypt_key))\n",
"print(np.asarray(h.decrypt_key))"
],
"execution_count": 12,
"outputs": [
{
"output_type": "stream",
"text": [
"[[22 5 24 8 12 6 22 11 27 22]\n",
" [ 9 19 3 29 15 1 10 25 13 1]\n",
" [13 11 6 6 1 7 27 7 4 28]\n",
" [22 13 27 5 19 20 29 17 21 12]\n",
" [27 11 0 19 3 19 20 28 24 18]\n",
" [ 6 22 16 2 8 21 25 10 24 29]\n",
" [12 22 9 10 2 29 15 0 25 24]\n",
" [ 7 14 0 5 13 25 29 17 17 2]\n",
" [ 9 22 11 13 20 18 4 16 21 29]\n",
" [ 1 21 11 3 22 19 23 12 10 20]]\n",
"CPU times: user 1.7 ms, sys: 981 µs, total: 2.68 ms\n",
"Wall time: 7.96 ms\n",
"[[22 5 24 8 12 6 22 11 27 22]\n",
" [ 9 19 3 29 15 1 10 25 13 1]\n",
" [13 11 6 6 1 7 27 7 4 28]\n",
" [22 13 27 5 19 20 29 17 21 12]\n",
" [27 11 0 19 3 19 20 28 24 18]\n",
" [ 6 22 16 2 8 21 25 10 24 29]\n",
" [12 22 9 10 2 29 15 0 25 24]\n",
" [ 7 14 0 5 13 25 29 17 17 2]\n",
" [ 9 22 11 13 20 18 4 16 21 29]\n",
" [ 1 21 11 3 22 19 23 12 10 20]]\n",
"[[87 70 63 78 76 58 59 36 49 45]\n",
" [ 1 55 48 94 4 50 57 19 13 8]\n",
" [12 95 11 13 12 71 59 20 58 18]\n",
" [22 16 87 39 50 87 50 80 91 31]\n",
" [26 29 25 33 45 39 18 13 39 83]\n",
" [81 38 71 29 85 23 13 50 70 21]\n",
" [26 58 66 15 4 95 16 15 40 69]\n",
" [48 33 30 76 60 15 8 90 15 28]\n",
" [20 64 23 26 6 48 10 82 57 45]\n",
" [19 8 18 26 32 25 60 14 51 2]]\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "LO2TeoXj4wMT",
"colab_type": "code",
"outputId": "28d7a3d7-786f-49da-8cf9-c526957bf701",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 102
}
},
"source": [
"txt = \"cpdef char * process_text(self, const unsigned char[:] text):\"\n",
"# with open('setup_prime_sieves.py') as f:\n",
"# txt = f.read().encode('ascii')\n",
"%time en = h.codec(bytes(txt, 'ascii'), 0)\n",
"# %lprun -f h.codec en = h.codec(b\"cpdef char * process_text(self, const unsigned char[:] text):\", 1)\n",
"# %timeit -n 500 h.encrypt(b\"cpdef char * process_text(self, const unsigned char[:] text):\")\n",
"print(en)"
],
"execution_count": 13,
"outputs": [
{
"output_type": "stream",
"text": [
"CPU times: user 109 µs, sys: 0 ns, total: 109 µs\n",
"Wall time: 84.6 µs\n",
"\r6?q=$2\n",
"wvc'IZhFctX}BnYR?8XPr'pWHs!<[\n",
" \"nNPbV{Vy&Mri4x\"a8\\_`\r\\zC{yVky\"\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "zFoCu2QW4wMf",
"colab_type": "code",
"outputId": "ac06e0ce-0a41-4e78-e6c6-ed40763b25f3",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 68
}
},
"source": [
"%time de = h.codec(bytes(en, 'ascii'), 1)\n",
"# %lprun -f h.codec en = h.codec(b\"cpdef char * process_text(self, const unsigned char[:] text):\", 1)\n",
"# %timeit -n 500 h.encrypt(b\"cpdef char * process_text(self, const unsigned char[:] text):\")\n",
"print(de)"
],
"execution_count": 14,
"outputs": [
{
"output_type": "stream",
"text": [
"CPU times: user 105 µs, sys: 0 ns, total: 105 µs\n",
"Wall time: 80.1 µs\n",
"cpdef char * process_text(self, const unsigned char[:] text)::::::::::\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "2EVL9LXL4wMo",
"colab_type": "code",
"outputId": "b7f101de-a505-489a-da84-21b799aa28ef",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 119
}
},
"source": [
"%timeit gcd_n(det, 97)\n",
"%timeit gcd_n2(det, 97)\n",
"%timeit gcd_c(det, 97)"
],
"execution_count": 15,
"outputs": [
{
"output_type": "stream",
"text": [
"The slowest run took 122.36 times longer than the fastest. This could mean that an intermediate result is being cached.\n",
"1000000 loops, best of 3: 301 ns per loop\n",
"The slowest run took 10.59 times longer than the fastest. This could mean that an intermediate result is being cached.\n",
"1000000 loops, best of 3: 540 ns per loop\n",
"The slowest run took 33.70 times longer than the fastest. This could mean that an intermediate result is being cached.\n",
"10000000 loops, best of 3: 187 ns per loop\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "ITY07MoV4wMy",
"colab_type": "code",
"outputId": "28ab749a-e7d4-453b-8807-6c03d2cf8f21",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 54
}
},
"source": [
"# %lprun -f HillCipher.make_decrypt_key h = HillCipher(a)\n",
"%time h = HillCipher(a)"
],
"execution_count": 0,
"outputs": [
{
"output_type": "stream",
"text": [
"CPU times: user 435 µs, sys: 16 µs, total: 451 µs\n",
"Wall time: 328 µs\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "galsXZgK4wM6",
"colab_type": "code",
"outputId": "69bddffd-4fe2-4ef8-ddcd-5cc0e71ef9cb",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 72
}
},
"source": [
"txt = 'HELP'\n",
"txt2 = bytes(txt, 'ascii')\n",
"%lprun -f h.codec c = h.codec(txt2, 0)\n",
"%timeit c = h.codec(txt2, 0)\n",
"print(c)"
],
"execution_count": 0,
"outputs": [
{
"output_type": "stream",
"text": [
"The slowest run took 8.73 times longer than the fastest. This could mean that an intermediate result is being cached.\n",
"100000 loops, best of 3: 5.81 µs per loop\n",
"#T|?LqgH9&\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "Fb40FeKd4wNE",
"colab_type": "code",
"outputId": "5b11adaf-8d30-4039-d3aa-b8f09508a007",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 72
}
},
"source": [
"txt2 = bytes(c, 'ascii')\n",
"%lprun -f h.codec d = h.codec(txt2, 1)\n",
"%timeit d = h.codec(txt2, 1)\n",
"print(d)"
],
"execution_count": 0,
"outputs": [
{
"output_type": "stream",
"text": [
"The slowest run took 8.46 times longer than the fastest. This could mean that an intermediate result is being cached.\n",
"100000 loops, best of 3: 6.15 µs per loop\n",
"HELPPPPPPP\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "WVbgb7rL4wNM",
"colab_type": "code",
"colab": {}
},
"source": [
""
],
"execution_count": 0,
"outputs": []
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment