예제 #1
0
def _solve_set3_ch17():
    (ciphertext, iv) = cbc_padding_oracle_attack_sample_enc()
    block_size = 16
    ciphertext = iv + ciphertext
    plaintext = ""
    while (len(ciphertext) / block_size) > 1:
        c0 = ciphertext[-block_size * 2:-block_size]
        c1 = ciphertext[-block_size:]
        plainblock = ""
        for j in range(block_size, 0, -1):
            padd_byte = chr(block_size - j + 1)
            _c0 = c0[:j] + xor.xor(
                c0[j:], xor.xor(plainblock, padd_byte * (ord(padd_byte) - 1)))
            flag = False
            for k in range(1, 0x100):
                scr = "\x00" * (j - 1) + chr(k) + "\x00" * (block_size - j)
                if cbc_padding_oracle_attack_sample_dec(
                        xor.xor(_c0, scr) + c1, iv):
                    plainblock = xor.xor(chr(k), padd_byte) + plainblock
                    flag = True
            if not flag:
                #print "no byte!"
                plainblock = padd_byte + plainblock
        ciphertext = ciphertext[:-16]
        plaintext = plainblock + plaintext
    print pkcs7.unpad(plaintext)
예제 #2
0
def _solve_set2_ch16():
    ciphertext = cbc_bitflip_attack_sample_enc("\x00" * 16)
    print cbc_bitflip_attack_sample_dec(ciphertext)
    C1 = ciphertext[16:32]
    p2_ = ";admin=true;;;;;"
    p2 = "\x00" * 16
    C1_ = xor.xor(xor.xor(C1, p2), p2_)
    ciphertext = ciphertext[:16] + C1_ + ciphertext[32:]
    print cbc_bitflip_attack_sample_dec(ciphertext)
예제 #3
0
    def __xex(self, data, start, size):
        E = AES.new(self.masterKey, AES.MODE_ECB)
        c = ""

        i = start
        for j in range(BLOCK_SIZE):
            x = xor(E.encrypt(pack(">QQ", 0, i)), 2**j)
            c += xor(xor(E.encrypt(data[j:j + 16], x)), x)

        return c
예제 #4
0
def encrypt_cbc_128(plaintext, iv, key):
	cipher = AES.new(key, AES.MODE_ECB, "")
	ciphertext = ""
	plaintext = pkcs7.pad(plaintext, 16)
	for i in range(0, len(plaintext) / 16):
		block = plaintext[16 * i : 16 * (i + 1)]
		if i == 0:
			ciphertext = ciphertext + cipher.encrypt(xor.xor(block, iv))
		else:
			prev_block = ciphertext[16 * (i - 1): 16 * i]
			ciphertext = ciphertext + cipher.encrypt(xor.xor(block, prev_block))
	return ciphertext
예제 #5
0
    def read(self, blockNum, size):
        E = AES.new(self.masterKey, AES.MODE_ECB)
        c = ""

        i = blockNum
        block = Block()
        self.sim.readBlock(self.disk, i, block)
        data = block.getData()

        for j in range(BLOCK_SIZE()):
            x = xor(E.encrypt(pack(">QQ", 0, i)), str(2**j))
            c += xor(xor(E.decrypt(data[j:j + 16]), x), x)

        return c
예제 #6
0
    def encrypt(self, p):
        p = self._padder.pad(p)
        c = b""
        for i in range(0, len(p), self.block_size):
            current_block = p[i:i + self.block_size]
            if i == 0:
                temp = xor(current_block, self.iv)
                c += self._ecb.encrypt(temp)
            else:
                previous_block = p[i - self.block_size:i]
                temp = xor(current_block, previous_block)
                c += self._ecb.encrypt(temp)

        return c
예제 #7
0
def decrypt_cbc_128(ciphertext, iv, key, no_unpad = False):
	cipher = AES.new(key, AES.MODE_ECB, "")
	plaintext = ""
	for i in range(0, len(ciphertext) / 16):
		block = ciphertext[16 * i : 16 * (i + 1)]
		if i == 0:
			plaintext = plaintext + xor.xor(cipher.decrypt(block), iv)
		else:
			prev_block = ciphertext[16 * (i - 1): 16 * i]
			plaintext = plaintext + xor.xor(cipher.decrypt(block), prev_block)
	if no_unpad:
		return plaintext
	else:
		return pkcs7.unpad(plaintext)
예제 #8
0
    def write(self, data, blockNum, size):
        #size = int(ceil(float(size) / BLOCK_SIZE()))
        #blockNum = self.sim.freeBlock(self.disk, size)

        E = AES.new(self.masterKey, AES.MODE_ECB)
        c = ""

        i = blockNum
        print(len(data))
        for j in range(BLOCK_SIZE() + 1, 16):
            x = xor(E.encrypt(pack(">QQ", 0, i)), str(2**j))
            c += xor(xor(E.encrypt(data[j:j + 16]), x), x)

        block = Block(c)
        self.sim.writeBlock(self.disk, i, block)
        return 0
예제 #9
0
def encrypt(ptext, key, iv):
	obj2 = AES.new(key, AES.MODE_ECB)
	prev_cipblock=iv
	ciptext=bytearray()
	#print (len(ptext))
	for x in range(0, len(ptext), 16):
		#print (x)
		pblock=ptext[x:(x+16)]
		if len(pblock)<16:
			pblock=padding.padding(pblock, 16)

		a = xor.xor(pblock, prev_cipblock)
		#a = a.decode('UTF-8')
		b = obj2.encrypt(bytes(a))
		#print (b)
		#a = xor.xor(a, prev_cipblock)
		#a=a.decode('UTF-8')
		ciptext+=b
		#print(b)

		prev_cipblock=b
		#f=input()
		
	
	return ciptext
def get_possible_plaintexts(ciphertext, keys):
    plaintexts = []
    for key in keys:
        plaintext = unhexlify(xor(ciphertext, key))
        plaintexts.append((key[:2], plaintext))

    return plaintexts
예제 #11
0
def hashfun(x):
	len_x = len(x)
	hx = '00000000'
	'''Keep performing XOR operation with consecutive bytes of x'''
	for i in xrange(0,len_x-8+1,8):
		hx = xor(hx,x[i:i+8])

	return hx.zfill(32)
def hamming_distance(x, y):
    bytes = xor(x, y)

    collection = ""
    for byte in bytes:
        collection += "{0:08b}".format(byte)

    return collection.count("1")
예제 #13
0
    def test_xor_solution(self):
        # cryptopals hex input strings
        hex_1 = "1c0111001f010100061a024b53535009181c"
        hex_2 = "686974207468652062756c6c277320657965"

        # test if it's working
        b64_answer = "746865206b696420646f6e277420706c6179"

        self.assertEqual(xor.xor(hex_1, hex_2), b64_answer)
예제 #14
0
파일: sha.py 프로젝트: aaron-otis/SHA1
def hmac(key, data):
    s = sha1()
    t = sha1()
    ipad = b"\x36" * 64
    opad = b"\x5C" * 64

    if len(key) < 64:
        key += b"\x00" * (64 - len(key))
    elif len(key) > 64 * 2:
        u = sha1()
        u.update(key)
        key = u.hexdigest()
        key += b"\x00" * (64 - len(key))

    s.update(xor(key, ipad) + data)
    t.update(xor(key, opad) + s.digest())

    return t.hexdigest()
예제 #15
0
def encryptAES_CBC(decrypt: bytes, key: bytes, iv: bytes):
    if len(iv) != 16:
        raise ValueError('IV must have a 16 bytes block size.')
    decrypt = pad(decrypt, 16)
    encrypt = bytes()
    for i in range(int(len(decrypt) / 16)):
        block = xor(decrypt[i * 16:(i + 1) * 16],
                    iv if i == 0 else encrypt[(i - 1) * 16:i * 16])
        encrypt += encryptAES_ECB(block, key)
    return encrypt
예제 #16
0
파일: aes.py 프로젝트: amlweems/zngnfnab
def cbc_decrypt(enc, key, iv, block_size=16):
    cipher = AES.new(key, AES.MODE_ECB)
    dec = ''
    prev = iv
    for n in range(0, len(enc), block_size):
        block = enc[n:n+block_size]
        dec_block = cipher.decrypt(block)
        dec += xor(dec_block, prev)
        prev = block
    return dec
예제 #17
0
파일: aes.py 프로젝트: amlweems/zngnfnab
def cbc_encrypt(text, key, iv, block_size=16):
    cipher = AES.new(key, AES.MODE_ECB)
    enc = ''
    prev = iv
    for n in range(0, len(text), block_size):
        block = xor(text[n:n+block_size], prev)
        enc_block = cipher.encrypt(block)
        enc += enc_block
        prev = enc_block
    return enc
예제 #18
0
def decryptAES_CBC(encrypt: bytes, key: bytes, iv: bytes):
    if len(iv) != 16:
        raise ValueError('IV must have a 16 bytes block size.')
    if len(encrypt) % 16 != 0:
        raise ValueError('The encrypted data must be 16 bytes padded.')
    middecrypt = pad(decryptAES_ECB(encrypt, key), 16)
    decrypt = bytes()
    for i in range(int(len(encrypt) / 16)):
        decrypt += xor(middecrypt[i * 16:(i + 1) * 16],
                       iv if i == 0 else encrypt[(i - 1) * 16:i * 16])
    return unpad(decrypt)
예제 #19
0
파일: cbccts.py 프로젝트: mdornseif/ddns
 def encrypt(self, iv, plaintext):
     bs = self.block_size
     lp = len(plaintext)
     last = self.encrypt_func(iv)
     if lp < bs:
         return xor(last[:lp], plaintext)
     r = StringIO()
     m = len(plaintext) % bs
     if m == 0:
         for i in xrange(0, lp, bs):
             last = self.encrypt_func(xor(last, plaintext[i:i + bs]))
             r.write(last)
     else:
         for i in xrange(0, lp - bs - m, bs):
             last = self.encrypt_func(xor(last, plaintext[i:i + bs]))
             r.write(last)
         cn = self.encrypt_func(xor(last, plaintext[-bs-m:-m]))
         r.write(self.encrypt_func(xor(cn, plaintext[-m:] + ('\000' * (bs - m)))))
         r.write(cn[:m])
     return r.getvalue()
def get_hamming_distance(hex_str1, hex_str2):
    xor_res = xor(hex_str1, hex_str2)
    xor_res = unhexlify(xor_res)

    hamming_distance = 0
    for byte in xor_res:
        bits = bin(byte)
        hamming_distance += bits.count("1")

    hamming_distance /= len(xor_res)

    return hamming_distance
예제 #21
0
    def decrypt(self, c):
        """
        Reverse the encrypt operation.
        The encrypt operation first xors the current and previous block, and then performs
        the encryption. In order to decrypt this data, we need to reverse that procedure;
        first, decrypt a block of c, then xor it. This will result in p.
        :param c:
        :return:
        """
        p = b""
        for i in range(0, len(c), self.block_size):
            current_block = c[i:i + self.block_size]
            if i == 0:
                temp = self._ecb.decrypt(current_block)
                p += xor(temp, self.iv)
            else:
                previous_block = c[i - self.block_size:i]
                temp = self._ecb.decrypt(current_block)
                p += xor(temp, previous_block)

        p = self._padder.unpad(p)
        return p
예제 #22
0
 def encrypt(self, iv, plaintext):
     bs = self.block_size
     lp = len(plaintext)
     last = self.encrypt_func(iv)
     if lp < bs:
         return xor(last[:lp], plaintext)
     r = StringIO()
     m = len(plaintext) % bs
     if m == 0:
         for i in xrange(0, lp, bs):
             last = self.encrypt_func(xor(last, plaintext[i:i + bs]))
             r.write(last)
     else:
         for i in xrange(0, lp - bs - m, bs):
             last = self.encrypt_func(xor(last, plaintext[i:i + bs]))
             r.write(last)
         cn = self.encrypt_func(xor(last, plaintext[-bs - m:-m]))
         r.write(
             self.encrypt_func(xor(cn,
                                   plaintext[-m:] + ('\000' * (bs - m)))))
         r.write(cn[:m])
     return r.getvalue()
예제 #23
0
파일: cbccts.py 프로젝트: mdornseif/ddns
 def decrypt(self, iv, ciphertext):
     bs = self.block_size
     lc = len(ciphertext)
     last = self.encrypt_func(iv)
     if lc < bs:
         return xor(last[:lc], ciphertext)
     r = StringIO()
     m = len(ciphertext) % bs
     if m == 0:
         for i in xrange(0, lc, bs):
             nl = ciphertext[i:i + bs]
             r.write(xor(last, self.decrypt_func(nl)))
             last = nl
     else:
         for i in xrange(0, lc - bs - m, bs):
             nl = ciphertext[i:i + bs]
             r.write(xor(last, self.decrypt_func(nl)))
             last = nl
         pn = xor(self.decrypt_func(ciphertext[-bs-m:-m]), ciphertext[-m:] + ('\000' * (bs - m)))
         r.write(xor(last, self.decrypt_func(ciphertext[-m:] + pn[m:])))
         r.write(pn[:m])
     return r.getvalue()
예제 #24
0
 def decrypt(self, iv, ciphertext):
     bs = self.block_size
     lc = len(ciphertext)
     last = self.encrypt_func(iv)
     if lc < bs:
         return xor(last[:lc], ciphertext)
     r = StringIO()
     m = len(ciphertext) % bs
     if m == 0:
         for i in xrange(0, lc, bs):
             nl = ciphertext[i:i + bs]
             r.write(xor(last, self.decrypt_func(nl)))
             last = nl
     else:
         for i in xrange(0, lc - bs - m, bs):
             nl = ciphertext[i:i + bs]
             r.write(xor(last, self.decrypt_func(nl)))
             last = nl
         pn = xor(self.decrypt_func(ciphertext[-bs - m:-m]),
                  ciphertext[-m:] + ('\000' * (bs - m)))
         r.write(xor(last, self.decrypt_func(ciphertext[-m:] + pn[m:])))
         r.write(pn[:m])
     return r.getvalue()
예제 #25
0
def degenerate_check(ciphertext: Term,
                     previous_ciphertexts: List[Term]) -> bool:
    """
    Check if symbolic history is degenerate
    """
    degen = False
    previous_ciphertexts.append(ciphertext)
    seq = zero
    for t in previous_ciphertexts:
        seq = xor(seq, t)
        if seq == zero:
            degen = True
            break
    return degen
예제 #26
0
def cbc_decrypt(c, k, iv):
    if len(k) not in (16, 24, 32):
        raise Exception('InvalidKeyLength')
    if len(c) % 16 != 0:
        raise Exception('InvalidCiphertextLength')
    if len(iv) != 16:
        raise Exception('InvalidIVLength')
    p = b''
    prev_cblock = iv
    for cblock in chunked(c, 16):
        cblock = bytes(cblock)
        pblock = xor(ecb_decrypt(cblock, k), prev_cblock)
        prev_cblock = cblock
        p += pblock
    return p
예제 #27
0
def cbc_encrypt(p, k, iv):
    if len(k) not in (16, 24, 32):
        raise Exception('InvalidKeyLength')
    if len(p) % 16 != 0:
        raise Exception('InvalidPlaintextLength')
    if len(iv) != 16:
        raise Exception('InvalidIVLength')
    c = b''
    prev_cblock = iv
    for pblock in chunked(p, 16):
        pblock = bytes(pblock)
        cblock = ecb_encrypt(xor(pblock, prev_cblock), k)
        prev_cblock = cblock
        c += cblock
    return c
예제 #28
0
def main():
    file_obj = ''
    cipherlist = []
    with open('files/4.txt') as f:
        for line in f:
            cipherlist.append(line.strip().decode('hex'))

    max_score = 0
    max_string = ''

    for k in range(0, 255):
        key = chr(k)
        for i in cipherlist:
            x = xor(i, key)
            sc = score_text(x)
            if sc > max_score:
                max_score = sc
                max_string = x
    print('Final score: {}, string: {}'.format(str(max_score), max_string))
예제 #29
0
def encrypt_ecb_cbc(message, key, iv):
    block_length = len(key)

    if len(iv) != block_length:
        raise Exception("iv must match key length!")

    padded_message = pad(message, block_length)

    blocks = list(grouper(padded_message, block_length))
    cipher = AES.new(key, AES.MODE_ECB)
    last_block = iv
    encrypted_blocks = []

    for block in blocks:
        encrypted_block = cipher.encrypt(xor(last_block, block))
        encrypted_blocks.append(encrypted_block)
        last_block = encrypted_block

    return b"".join(encrypted_blocks)
예제 #30
0
def decrypt_ecb_cbc(cipher_text, key, iv):
    block_length = len(key)

    if len(iv) != block_length:
        raise Exception("iv must match key length!")

    blocks = list(grouper(cipher_text, block_length))
    cipher = AES.new(key, AES.MODE_ECB)
    last_block = iv
    plain_blocks = []

    for block in blocks:
        decrypted_block = cipher.decrypt(bytes(block))
        plain_block = xor(last_block, decrypted_block)
        plain_blocks.append(plain_block)
        last_block = block

    plain_text = pad_strip(b"".join(plain_blocks))
    return plain_text
예제 #31
0
def decrypt_aes_cbc(message, key, iv=(chr(0) * 16).encode()):
    '''
    Args:
        message (bytes): The message to be derypted
        key (bytes): The key to use in the decryption
        iv (optional bytes): The initialization vector for CBC mode
    Return:
        Decrypted message
    '''
    block_size = 16
    enc_message = [
        message[i:i + block_size] for i in range(0, len(message), block_size)
    ]
    dec_message = []
    dec_string = iv
    for i in range(0, len(enc_message)):
        decrypted = xor(decrypt_aes_ecb(enc_message[i], key), dec_string)
        dec_message.append(decrypted.decode())
        dec_string = enc_message[i]
    return ''.join(dec_message)
예제 #32
0
def decrypt(ciptext, key, iv):
	obj2 = AES.new(key, AES.MODE_ECB)
	prev_cipblock=iv
	ptext=bytearray()
	for x in range(0, len(ciptext), 16):
		cipblock=ciptext[x:(x+16)]
		#if len(cipblock)<16:
		#	cipblock=padding.padding(cipblock, 16)
		#a = cipblock.decode('Utf-8')
		a = obj2.decrypt(bytes(cipblock))
		#print (a)
		a = xor.xor(a, prev_cipblock)
		#a=a.decode('UTF-8')
		ptext+=a
		#print(a)
		x+=16
		prev_cipblock=cipblock
		#f=input()

	
	return ptext
예제 #33
0
def encrypt_aes_cbc(message, key, iv=(chr(0) * 16).encode()):
    '''
    Args:
        message (bytes): The message to be encrypted
        key (bytes): The key to use in the encrypted
        iv (optional bytes): The initialization vector for CBC mode
    Return:
        Encrypted message
    '''
    block_size = 16
    message = padding(message)
    dec_message = [
        message[i:i + block_size] for i in range(0, len(message), block_size)
    ]
    enc_message = []
    enc_string = iv
    for i in range(0, len(dec_message)):
        encrypted = encrypt_aes_ecb(xor(dec_message[i], enc_string), key,
                                    False)
        enc_message.append(encrypted)
        enc_string = enc_message[i]
    return b''.join(enc_message)
예제 #34
0
#!/usr/bin/env python3
# coding: utf-8
"""
Implement repeating-key XOR.
https://cryptopals.com/sets/1/challenges/5
"""

from binascii import hexlify
from xor import xor

ps = ("Burning 'em, if you ain't quick and nimble\n"
      "I go crazy when I hear a cymbal")
ks = 'ICE'

p = bytes(ps, 'utf8')
k = bytes(ks, 'utf8')

e = xor(p, k)

print(hexlify(e).decode('utf8'))
예제 #35
0
def getSingleXORKey(s):
    freqtab = {}

    frlist = []
    f3 = open("freq.txt", "r")
    for line in f3:
        words = line.split()

        freqtab[words[0]] = float(words[1])
        frlist.append(words[0])
    mindev = 100.000
    ans = ""
    store = -1
    for i in range(0, 256):
        a = bytes([i] * (int)(len(s)))
        count = 0
        flag = 0
        dev = 0
        warn = 0
        freqline = {}
        freqline = freqline.fromkeys(frlist, 0)
        p = xor.xor(s, a)
        #print (p)
        try:
            p = p.decode('UTF-8')
        except Exception:

            continue
        #print (p)
        for j in range(0, len(p)):
            c = p[j]
            if ord(c) > 31:
                if c.isalpha():
                    count = count + 1
                    freqline[c.upper()] = freqline[c.upper()] + 1

            else:
                if (ord(c) != 10):
                    warn += 1
                continue
                #break

        if flag == 0:
            if (count <= 0):
                continue
            for key in freqline:

                freqline[key] = float(freqline[key]) / float(count)
                dev = dev + abs(freqline[key] - freqtab[key])

            dev = dev / float(count)
            dev += warn
            #print (dev)
            #print (i)
            if dev < mindev:
                ans = p
                mindev = dev
                store = i
    f3.close()
    #print (mindev)
    return (ans, store, mindev)
예제 #36
0
 def test_Xor_Str1OddLength_Succeeds(self):
     test_str1 = "11111"
     test_str2 = "2222"
     with self.assertRaises(ValueError):
         xor(test_str1, test_str2)
	#Demande au serveur à l'URL de CHALLENGE
	reponse_challenge = server.query(url_challenge)

	#On récupère le champ A -> normalement en UTF-8, il faut décoder l'hexadécimal en bytes, puis de bytes en unicode
	AxorM = reponse_challenge['A']

	#On récupère le champ B -> normalement en ASCII, il faut décoder l'hexadécimal en bytes, puis de bytes en ascii
	BxorM = reponse_challenge['B']

	#Transformation en bytes pour A et B
	AxorM_decode = base64.b16decode(AxorM, casefold=True)
	BxorM_decode = base64.b16decode(BxorM, casefold=True)

	#Calcul du XOR entre A et B (en bytes) -> élimination du masque M
	AxorB = xor(AxorM_decode, BxorM_decode)

	length_AxorB = len(AxorB)

	msg_AxorB = ""

	#Recherche du message avec Xor sur 0
	for i in range(0, length_AxorB):
		c = chr(xor_byte(AxorB[i], ord('0')))
		if (c.isalpha() == False) and c != "\n" and c != " " :
			c = chr(xor_byte(AxorB[i], ord('1')))
		msg_AxorB += str(c)

	#Impression des deux messages
	#print("msg 0 : {0}".format(msg_AxorB_0))
	#print("msg 1 : {0}".format(msg_AxorB_1))
예제 #38
0
		tup=prob3.getSingleXORKey(s)
		#print (len(tup))
		if(tup[1]==-1):
			flag=1
			print ("Failed : "+ str(keysize))
			break
		keys.append(tup[1])
		dev+=tup[2]
		
	


	if flag==1:
		continue
	
	
	ans=xor.xor((bigstring.encode('UTF-8')), keys)

	dev = float(dev)/keysize

	ans=ans.decode('UTF-8')
	#print (ans)
	print (keysize)
	print(keys)
	print (dev/keysize)
	




예제 #39
0
import sys
import xor
import convert
import binascii


f1 = open("input5.txt", "r")

s = f1.read()

k = input("Enter key:")

s=s.encode("utf-8")

k = k.encode("utf-8")
p = xor.xor(s, k)
p = binascii.hexlify(p)
print (p)
f2 = open("output5.txt", "w")
f2.write(str(p))
f2.close()
f1.close()
예제 #40
0
def halfadder(a, b):
    return {'c':aand(a,b),'o':xor(a,b)}
예제 #41
0
def xnor(a, b):
    return nnot(xor(a,b))
예제 #42
0
import sys
import convert
import xor
import binascii

a = "1c0111001f010100061a024b53535009181c"
b = "686974207468652062756c6c277320657965"
a = binascii.unhexlify(a)
b = binascii.unhexlify(b)
c = xor.xor(a, b)
#c = convert.binarytohex(c)
print (binascii.hexlify(c))
예제 #43
0
linecur=0
for line in f2:
	linecur+=1
	line = line.rstrip('\n')
	#print line
	#k = raw_input()
	s = binascii.unhexlify(line)
	#print (s)
	for i in range(0,  256):
		a = bytes([i]*(int)(len(s)))
		count=0
		flag=0
		dev=0
		freqline={}
		freqline = freqline.fromkeys(frlist, 0)
		p = xor.xor(s, a)
		try:
			p = p.decode("utf-8")
			
		except Exception:
			#print ("Here")
			continue
		#print p
		#print (p)
		for j in range(0, len(p)):
			c = p[j]
			if ord(c)>31 and ord(c)<127 or ord(c)==10:
				if c.isalpha():
					count=count+1
					freqline[c.upper()]=freqline[c.upper()]+1
예제 #44
0
파일: matrix.py 프로젝트: lucasg/Cryptopals
import sys 
import collections

manpage = """ matrix of Xor files : python matrix.py [ list of files ] """


get_array = lambda m,i: [ m[j][i] for j in range(0, len(m)) if i < len(m[j]) ] 
get_printable = lambda array: filter(lambda c: c in xor.printable, array)
get_printable_with_zero = lambda array: filter(lambda c: 0 != ord(c) or c in xor.printable, array)
most_common_image = lambda m: [ collections.Counter(get_printable(get_array(m,i))).most_common(1) if len([x for x in get_printable(get_array(m,i))]) < 3/4.0*len([x for x in get_printable_with_zero(get_array(m,i))]) else (' ',0) for i in range(clen) ]



if __name__ == '__main__':


	if not len(sys.argv):
		print(manpage)

	else:
		m = []
		for i in range(2, len(sys.argv)):
			x = xor.xor(open(sys.argv[1], "rb").read(), open(sys.argv[i], "rb").read())
			m.append(x)

			# print (xor.hex_escape(','.join(x)))

		clen = len(open(sys.argv[1], "rb").read())
		# "Most Frequent for " + sys.argv[1] + " : "  + 
		print(''.join( t[0][0] if t != [] else '?' for t in most_common_image(m) ))