import datetime import bcrypt # the taste of summer strawberries straw = "le goût des fraises d'été" # summer ete = "été" def bytes2hex(byte_array: bytes): '''converts the byte_array into a string like [41 43 54]: a series of pairs of hexadecimal digits, surrounded by square brackets''' if type(byte_array) != bytes: raise TypeError('argument is not an array of bytes', byte_array) hex = ' '.join( format(b, '02x') for b in byte_array ) return f'[{hex}]' def demo_encode_decode(x: str): '''convert the argument (a string) into an array of bytes by encoding as UTF8, and convert back, printing results to demonstrate encoding and decoding.''' if type(x) != str: raise TypeError('argument is not a string', x) print(f'encoding x: {x}') b = x.encode('utf-8') y = b.decode('utf-8') print('x', x, type(x)) print('b', b, type(b)) print('y', y, type(y)) print(bytes2hex(b)) print('are x and y equal?', x==y) def bcrypt_string(input_string, prior=None, encoding='utf8'): if prior is None: prior = bcrypt.gensalt() else: prior = prior.encode(encoding) x = input_string.encode(encoding) y = bcrypt.hashpw(x, prior) output_string = y.decode(encoding) return output_string def bcrypt_timing(min_work=12, max_work=18): '''Bcrypt a particular string with a variety of work factors''' last_time = datetime.datetime.now() for i in range(min_work, max_work): # work factor is embedded in the salt part of the string salt = bcrypt.gensalt(rounds=i) h = bcrypt.hashpw('secret'.encode('utf8'), salt) now = datetime.datetime.now() time_diff = now - last_time last_time = now seconds = (time_diff.seconds + (time_diff.microseconds / float(1_000_000))) print(f"hashing 'secret' with work {i} takes {seconds} seconds") def signup(passwd, encoding='utf8'): '''Returns an encrypted password, as a string, suitable for storing in a database.''' prior = bcrypt.gensalt() x = passwd.encode(encoding) y = bcrypt.hashpw(x, prior) output_string = y.decode(encoding) return output_string def login(passwd, prior, encoding='utf8'): '''Returns true/false as to whether the user entered the correct password, given that the value stored in the database is 'prior'.''' p = prior.encode(encoding) x = passwd.encode(encoding) y = bcrypt.hashpw(x, p) output_string = y.decode(encoding) print(passwd, prior, x, y, output_string, sep="\n") return prior == output_string