In [3]:
alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
In [4]:
def mult_cipher(plaintext, key):
    """Multiply the number corresponding to each letter in plaintext by key modulo 26.  The key should be invertible 
    modulo 26, to ensure the message can be decrypted."""
    ciphertext = []
    
    for i in range(len(plaintext)):
        place_alpha = alphabet.find(plaintext[i])
        new_place = (key * place_alpha) % 26
        ciphertext.append(alphabet[new_place])
    return ciphertext
In [5]:
mult_cipher("ABCZ", 3)
Out[5]:
['A', 'D', 'G', 'X']
In [5]:
"".join(mult_cipher("HELLO", 3))
Out[5]:
'VMHHQ'
In [6]:
# to decrypt, use key=9, which is inverse of 3 modulo 26, since 3*9 = 27, and 27%26=1.  
mult_cipher('VMHHQ', 9)
Out[6]:
['H', 'E', 'L', 'L', 'O']
In [7]:
mult_cipher("HELLO", 0)
Out[7]:
['A', 'A', 'A', 'A', 'A']
In [8]:
alphabet[13]
Out[8]:
'N'
In [9]:
# below we are using key=2, which is not invertible mod 26
# both A,N get encrypted as A, which means that decryption is impossible
mult_cipher("ANB",2)
Out[9]:
['A', 'A', 'C']
In [11]:
factor(2^31-1)
Out[11]:
2147483647
In [13]:
factor(2^12311212)
Out[13]:
2^12311212
In [20]:
%%time
factor(2^183-1)
CPU times: user 503 ms, sys: 4.64 ms, total: 508 ms
Wall time: 512 ms
Out[20]:
7 * 367 * 55633 * 2305843009213693951 * 37201708625305146303973352041
In [12]:
%%time
# below is much faster than above factor computation, which means that sage cannot be just factoring 
# the two numbers and comparing the prime factors
gcd(2^183-1, 2^31-1)
CPU times: user 19 µs, sys: 5 µs, total: 24 µs
Wall time: 24.1 µs
Out[12]:
1
In [13]:
def my_gcd(a,b):
    """Returns gcd of a,b.  Computed using Euclidean algorithm."""
    if a==0:
        return b
    if b==0:
        return a
    if a<b:
        print(a,b%a)
        return my_gcd(a, b%a)
    if a>=b:
        print(a%b,b)
        return my_gcd(a%b,b)
In [14]:
my_gcd(100,17)
(15, 17)
(15, 2)
(1, 2)
(1, 0)
Out[14]:
1
In [18]:
%%time
my_gcd(2^31-1, 2^183-1)
(2147483647, 268435455)
(7, 268435455)
(7, 1)
(0, 1)
CPU times: user 984 µs, sys: 169 µs, total: 1.15 ms
Wall time: 821 µs
Out[18]:
1
In [22]:
my_gcd(2^31-1, 2^37-1)
(2147483647, 63)
(1, 63)
(1, 0)
Out[22]:
1
In [21]:
my_gcd(2^122,3^15*2^42)
(31895570082433073152, 63107160369505763328)
(31895570082433073152, 31211590287072690176)
(683979795360382976, 31211590287072690176)
(683979795360382976, 432499495855456256)
(251480299504926720, 432499495855456256)
(251480299504926720, 181019196350529536)
(70461103154397184, 181019196350529536)
(70461103154397184, 40096990041735168)
(30364113112662016, 40096990041735168)
(30364113112662016, 9732876929073152)
(1165482325442560, 9732876929073152)
(1165482325442560, 409018325532672)
(347445674377216, 409018325532672)
(347445674377216, 61572651155456)
(39582418599936, 61572651155456)
(39582418599936, 21990232555520)
(17592186044416, 21990232555520)
(17592186044416, 4398046511104)
(0, 4398046511104)
Out[21]:
4398046511104
In [20]:
2^42
Out[20]:
4398046511104