balanced"; for a given plaintext input 0 or 1, the ciphertext result is equally likely to be either 0 or 1 for a truly random key bit. The table below shows all four possible pairs of plaintext and key bits. It is clear that if nothing is known about the key or plaintext, nothing can be determined from the ciphertext alone. Other logical operations such and AND or OR do not have such a mapping (for example, AND would produce three 0's and one 1, so knowing that a given ciphertext bit is a 0 implies that there is a 2/3 chance that the original plaintext bit was a 0, as opposed to the ideal 1/2 chance in the case of XOR) Example implementation Example using the Python programming language. from os import urandom def genkey(length: int) -> bytes: """Generate key.""" return urandom(length) def xor_strings(s, t) -> bytes: """Concate xor two strings together.""" if isinstance(s, str): # Text strings contain single characters return "".join(chr(ord(a) ^ b) for a, b in zip(s, t)).encode('utf8') else: # Bytes objects contain integer values in the range 0-255 return bytes([a ^ b for a, b in zip(s, t)]) message = 'This is a secret message' print('Message:', message) key = genkey(len(message)) print('Key:', key) cipherText = xor_strings(message.encode('utf8'), key) print('cipherText:', cipherText) print('decrypted:', xor_strings(cipherText, key).decode('utf8')) # Verify if xor_strings(cipherText, key).decode('utf8') == message: print('Unit test passed') else: print('Unit test failed') See also Block cipher Vernam cipher Vigenère cipher References Notes Citations Sources Transcript of a lecture given by Prof. Tutte at the University of Waterloo Stream ciphers