Skip to content

Commit 125b90a

Browse files
authored
Merge branch 'master' into Upgrade-to-Python-3.8
2 parents 9155e1d + ab65a39 commit 125b90a

36 files changed

+1134
-284
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# The Algorithms - Python <!-- [![Build Status](https://travis-ci.org/TheAlgorithms/Python.svg)](https://travis-ci.org/TheAlgorithms/Python) -->
1+
# The Algorithms - Python
22
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg?logo=paypal&style=flat-square)](https://www.paypal.me/TheAlgorithms/100)&nbsp;
3-
[![Build Status](https://img.shields.io/travis/TheAlgorithms/Python.svg?label=Travis%20CI&logo=travis&style=flat-square)](https://travis-ci.org/TheAlgorithms/Python)&nbsp;
3+
[![Build Status](https://img.shields.io/travis/TheAlgorithms/Python.svg?label=Travis%20CI&logo=travis&style=flat-square)](https://travis-ci.com/TheAlgorithms/Python)&nbsp;
44
[![LGTM](https://img.shields.io/lgtm/alerts/github/TheAlgorithms/Python.svg?label=LGTM&logo=LGTM&style=flat-square)](https://lgtm.com/projects/g/TheAlgorithms/Python/alerts)&nbsp;
55
[![Gitter chat](https://img.shields.io/badge/Chat-Gitter-ff69b4.svg?label=Chat&logo=gitter&style=flat-square)](https://gitter.im/TheAlgorithms)&nbsp;
66
[![contributions welcome](https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=flat-square)](https://github.com/TheAlgorithms/Python/blob/master/CONTRIBUTING.md)&nbsp;

blockchain/chinese_remainder_theorem.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def chinese_remainder_theorem(n1, r1, n2, r2):
4444
(x, y) = extended_euclid(n1, n2)
4545
m = n1 * n2
4646
n = r2 * x * n1 + r1 * y * n2
47-
return ((n % m + m) % m)
47+
return (n % m + m) % m
4848

4949

5050
# ----------SAME SOLUTION USING InvertModulo instead ExtendedEuclid----------------
@@ -84,8 +84,8 @@ def chinese_remainder_theorem2(n1, r1, n2, r2):
8484
# import testmod for testing our function
8585
from doctest import testmod
8686

87-
if __name__ == '__main__':
88-
testmod(name='chinese_remainder_theorem', verbose=True)
89-
testmod(name='chinese_remainder_theorem2', verbose=True)
90-
testmod(name='invert_modulo', verbose=True)
91-
testmod(name='extended_euclid', verbose=True)
87+
if __name__ == "__main__":
88+
testmod(name="chinese_remainder_theorem", verbose=True)
89+
testmod(name="chinese_remainder_theorem2", verbose=True)
90+
testmod(name="invert_modulo", verbose=True)
91+
testmod(name="extended_euclid", verbose=True)

blockchain/diophantine_equation.py

+10-6
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ def diophantine(a, b, c):
1717
1818
"""
1919

20-
assert c % greatest_common_divisor(a, b) == 0 # greatest_common_divisor(a,b) function implemented below
20+
assert (
21+
c % greatest_common_divisor(a, b) == 0
22+
) # greatest_common_divisor(a,b) function implemented below
2123
(d, x, y) = extended_gcd(a, b) # extended_gcd(a,b) function implemented below
2224
r = c / d
2325
return (r * x, r * y)
@@ -32,6 +34,7 @@ def diophantine(a, b, c):
3234

3335
# n is the number of solution you want, n = 2 by default
3436

37+
3538
def diophantine_all_soln(a, b, c, n=2):
3639
"""
3740
>>> diophantine_all_soln(10, 6, 14)
@@ -66,6 +69,7 @@ def diophantine_all_soln(a, b, c, n=2):
6669

6770
# Euclid's Algorithm
6871

72+
6973
def greatest_common_divisor(a, b):
7074
"""
7175
>>> greatest_common_divisor(7,5)
@@ -117,8 +121,8 @@ def extended_gcd(a, b):
117121
# import testmod for testing our function
118122
from doctest import testmod
119123

120-
if __name__ == '__main__':
121-
testmod(name='diophantine', verbose=True)
122-
testmod(name='diophantine_all_soln', verbose=True)
123-
testmod(name='extended_gcd', verbose=True)
124-
testmod(name='greatest_common_divisor', verbose=True)
124+
if __name__ == "__main__":
125+
testmod(name="diophantine", verbose=True)
126+
testmod(name="diophantine_all_soln", verbose=True)
127+
testmod(name="extended_gcd", verbose=True)
128+
testmod(name="greatest_common_divisor", verbose=True)

blockchain/modular_division.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ def modular_division2(a, b, n):
7070

7171
# Extended Euclid's Algorithm : If d divides a and b and d = a*x + b*y for integers x and y, then d = gcd(a,b)
7272

73+
7374
def extended_gcd(a, b):
7475
"""
7576
>>> extended_gcd(10, 6)
@@ -116,6 +117,7 @@ def extended_euclid(a, b):
116117
# Euclid's Lemma : d divides a and b, if and only if d divides a-b and b
117118
# Euclid's Algorithm
118119

120+
119121
def greatest_common_divisor(a, b):
120122
"""
121123
>>> greatest_common_divisor(7,5)
@@ -140,10 +142,10 @@ def greatest_common_divisor(a, b):
140142
# Import testmod for testing our function
141143
from doctest import testmod
142144

143-
if __name__ == '__main__':
144-
testmod(name='modular_division', verbose=True)
145-
testmod(name='modular_division2', verbose=True)
146-
testmod(name='invert_modulo', verbose=True)
147-
testmod(name='extended_gcd', verbose=True)
148-
testmod(name='extended_euclid', verbose=True)
149-
testmod(name='greatest_common_divisor', verbose=True)
145+
if __name__ == "__main__":
146+
testmod(name="modular_division", verbose=True)
147+
testmod(name="modular_division2", verbose=True)
148+
testmod(name="invert_modulo", verbose=True)
149+
testmod(name="extended_gcd", verbose=True)
150+
testmod(name="extended_euclid", verbose=True)
151+
testmod(name="greatest_common_divisor", verbose=True)

ciphers/base64_cipher.py

+37-20
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,52 @@
1-
def encodeBase64(text):
2-
base64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
3-
1+
def encode_base64(text):
2+
r"""
3+
>>> encode_base64('WELCOME to base64 encoding 😁')
4+
'V0VMQ09NRSB0byBiYXNlNjQgZW5jb2Rpbmcg8J+YgQ=='
5+
>>> encode_base64('AÅᐃ𐀏🤓')
6+
'QcOF4ZCD8JCAj/CfpJM='
7+
>>> encode_base64('A'*60)
8+
'QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB\r\nQUFB'
9+
"""
10+
base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
11+
12+
byte_text = bytes(text, "utf-8") # put text in bytes for unicode support
413
r = "" # the result
5-
c = 3 - len(text) % 3 # the length of padding
14+
c = -len(byte_text) % 3 # the length of padding
615
p = "=" * c # the padding
7-
s = text + "\0" * c # the text to encode
16+
s = byte_text + b"\x00" * c # the text to encode
817

918
i = 0
1019
while i < len(s):
1120
if i > 0 and ((i / 3 * 4) % 76) == 0:
12-
r = r + "\r\n"
21+
r = r + "\r\n" # for unix newline, put "\n"
1322

14-
n = (ord(s[i]) << 16) + (ord(s[i + 1]) << 8) + ord(s[i + 2])
23+
n = (s[i] << 16) + (s[i + 1] << 8) + s[i + 2]
1524

1625
n1 = (n >> 18) & 63
1726
n2 = (n >> 12) & 63
1827
n3 = (n >> 6) & 63
1928
n4 = n & 63
2029

21-
r += base64chars[n1] + base64chars[n2] + base64chars[n3] + base64chars[n4]
30+
r += base64_chars[n1] + base64_chars[n2] + base64_chars[n3] + base64_chars[n4]
2231
i += 3
2332

2433
return r[0 : len(r) - len(p)] + p
2534

2635

27-
def decodeBase64(text):
28-
base64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
36+
def decode_base64(text):
37+
r"""
38+
>>> decode_base64('V0VMQ09NRSB0byBiYXNlNjQgZW5jb2Rpbmcg8J+YgQ==')
39+
'WELCOME to base64 encoding 😁'
40+
>>> decode_base64('QcOF4ZCD8JCAj/CfpJM=')
41+
'AÅᐃ𐀏🤓'
42+
>>> decode_base64("QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB\r\nQUFB")
43+
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
44+
"""
45+
base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
2946
s = ""
3047

3148
for i in text:
32-
if i in base64chars:
49+
if i in base64_chars:
3350
s += i
3451
c = ""
3552
else:
@@ -43,28 +60,28 @@ def decodeBase64(text):
4360
if c == "==":
4461
p = "AA"
4562

46-
r = ""
63+
r = b""
4764
s = s + p
4865

4966
i = 0
5067
while i < len(s):
5168
n = (
52-
(base64chars.index(s[i]) << 18)
53-
+ (base64chars.index(s[i + 1]) << 12)
54-
+ (base64chars.index(s[i + 2]) << 6)
55-
+ base64chars.index(s[i + 3])
69+
(base64_chars.index(s[i]) << 18)
70+
+ (base64_chars.index(s[i + 1]) << 12)
71+
+ (base64_chars.index(s[i + 2]) << 6)
72+
+ base64_chars.index(s[i + 3])
5673
)
5774

58-
r += chr((n >> 16) & 255) + chr((n >> 8) & 255) + chr(n & 255)
75+
r += bytes([(n >> 16) & 255]) + bytes([(n >> 8) & 255]) + bytes([n & 255])
5976

6077
i += 4
6178

62-
return r[0 : len(r) - len(p)]
79+
return str(r[0 : len(r) - len(p)], "utf-8")
6380

6481

6582
def main():
66-
print(encodeBase64("WELCOME to base64 encoding"))
67-
print(decodeBase64(encodeBase64("WELCOME to base64 encoding")))
83+
print(encode_base64("WELCOME to base64 encoding 😁"))
84+
print(decode_base64(encode_base64("WELCOME to base64 encoding 😁")))
6885

6986

7087
if __name__ == "__main__":

ciphers/caesar_cipher.py

+35-34
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,62 @@
1-
def encrypt(strng, key):
2-
encrypted = ""
3-
for x in strng:
4-
indx = (ord(x) + key) % 256
5-
if indx > 126:
6-
indx = indx - 95
7-
encrypted = encrypted + chr(indx)
8-
return encrypted
1+
def encrypt(input_string: str, key: int) -> str:
2+
result = ''
3+
for x in input_string:
4+
if not x.isalpha():
5+
result += x
6+
elif x.isupper():
7+
result += chr((ord(x) + key - 65) % 26 + 65)
8+
elif x.islower():
9+
result += chr((ord(x) + key - 97) % 26 + 97)
10+
return result
911

1012

11-
def decrypt(strng, key):
12-
decrypted = ""
13-
for x in strng:
14-
indx = (ord(x) - key) % 256
15-
if indx < 32:
16-
indx = indx + 95
17-
decrypted = decrypted + chr(indx)
18-
return decrypted
13+
def decrypt(input_string: str, key: int) -> str:
14+
result = ''
15+
for x in input_string:
16+
if not x.isalpha():
17+
result += x
18+
elif x.isupper():
19+
result += chr((ord(x) - key - 65) % 26 + 65)
20+
elif x.islower():
21+
result += chr((ord(x) - key - 97) % 26 + 97)
22+
return result
1923

2024

21-
def brute_force(strng):
25+
def brute_force(input_string: str) -> None:
2226
key = 1
23-
decrypted = ""
27+
result = ''
2428
while key <= 94:
25-
for x in strng:
29+
for x in input_string:
2630
indx = (ord(x) - key) % 256
2731
if indx < 32:
2832
indx = indx + 95
29-
decrypted = decrypted + chr(indx)
30-
print("Key: {}\t| Message: {}".format(key, decrypted))
31-
decrypted = ""
33+
result = result + chr(indx)
34+
print(f'Key: {key}\t| Message: {result}')
35+
result = ''
3236
key += 1
3337
return None
3438

3539

3640
def main():
3741
while True:
38-
print("-" * 10 + "\n**Menu**\n" + "-" * 10)
39-
print("1.Encrpyt")
40-
print("2.Decrypt")
41-
print("3.BruteForce")
42-
print("4.Quit")
42+
print(f'{"-" * 10}\n Menu\n{"-", * 10}')
43+
print(*["1.Encrpyt", "2.Decrypt", "3.BruteForce", "4.Quit"], sep='\n')
4344
choice = input("What would you like to do?: ")
4445
if choice not in ["1", "2", "3", "4"]:
4546
print("Invalid choice, please enter a valid choice")
4647
elif choice == "1":
47-
strng = input("Please enter the string to be encrypted: ")
48-
key = int(input("Please enter off-set between 1-94: "))
48+
input_string = input("Please enter the string to be encrypted: ")
49+
key = int(input("Please enter off-set between 0-25: "))
4950
if key in range(1, 95):
50-
print(encrypt(strng.lower(), key))
51+
print(encrypt(input_string.lower(), key))
5152
elif choice == "2":
52-
strng = input("Please enter the string to be decrypted: ")
53+
input_string = input("Please enter the string to be decrypted: ")
5354
key = int(input("Please enter off-set between 1-94: "))
5455
if key in range(1, 95):
55-
print(decrypt(strng, key))
56+
print(decrypt(input_string, key))
5657
elif choice == "3":
57-
strng = input("Please enter the string to be decrypted: ")
58-
brute_force(strng)
58+
input_string = input("Please enter the string to be decrypted: ")
59+
brute_force(input_string)
5960
main()
6061
elif choice == "4":
6162
print("Goodbye.")

0 commit comments

Comments
 (0)