# Is this a good encryption algorithm?

I've never had a serious attempt at writing an encryption algorithm before, and haven't read much on the subject. I have tried to write an encryption algorithm (of sorts), I would just like to see if anyone thinks it's any good. (Obviously, it's not going to be comparable to those actually used, given that it's a first attempt)

Without further adieu:

def encode(string, giveUserKey = False, doubleEncode = True):
encoded = [] #Numbers representing encoded characters
keys = [] #Key numbers to unlonk code
fakes = [] #Which items in "encoded" are fake
#All of these are stored in a file

if giveUserKey:
userkey = random.randrange(2 ** 10,  2 ** 16)
# Key given to the user, entered during decryption for confirmation
# Could change range for greater security
else:
userkey = 1

for char in string:
ordChar = ord(char)
key = random.randrange(sys.maxsize)
encoded.append(hex((ordChar + key) * userkey))
keys.append(hex(key))

if random.randrange(fakeRate) == 0:
fake = hex(random.randrange(sys.maxsize) * userkey)
encoded.append(fake)
fakes.append(fake)

if doubleEncode:
encoded = [string.encode() for string in encoded]
keys = [string.encode() for string in keys]
fakes = [string.encode() for string in fakes]

hashValue = hex(hash("".join([str(obj) for obj in encoded + keys + fakes]))).encode()

return encoded, keys, hashValue, fakes, userkey

def decode(encoded, keys, hashValue, fakes, userkey = 1):
if hash("".join([str(obj) for obj in encoded + keys + fakes])) != eval(hashValue):
#File has been tampered with, possibly attempted reverse-engineering
return "ERROR"

for fake in fakes:
encoded.remove(fake)

decoded = ""

for i in range(len(keys)):
j = eval(encoded[i]) / userkey
decoded += chr(int(j - eval(keys[i])))

return decoded

• usually an encryption algo takes input data and a key(private/symmetric) then outputs cipher. What's with fakes and keys in your case? – SparKot Mar 5 '13 at 16:49
• "fakes" are fake bits of data inserted in to the code. "keys" are the keys from the file used to determine what the characters should actually be. – user1149589 Mar 5 '13 at 16:53
• If two parties say A & B, then isn't it necessary to exchange these fakes, keys along with actual cipher and Key(public/symmetric)? – SparKot Mar 5 '13 at 16:55
• I don't quite know what you mean. fakes and keys are exchanged in that they are written in to the file which is exchanged. (There is then "userkey" which is not written in to the file. It can be specified by the encryptor whether this is needed. It is then told to them and needs to be entered for decryption). – user1149589 Mar 5 '13 at 17:01

## 1 Answer

Firstly, your encryption is useless. Just run this one line of python code:

print reduce(fractions.gcd, map(eval, encoded))


And it will tell you what your user key is (with a pretty high probability).

Your algorithm is really obfuscation, not encrytion. Encryption is designed so that even if you know the algorithm, but not the key, you can't decryt the message. But your algorithm is basically designed to make it less obvious what the parts mean, not make it hard to decrypt without the key. As demonstrated, retrieving the key is trivial anyways.

def encode(string, giveUserKey = False, doubleEncode = True):


Python convention is lowercase_with_underscores for local names

    encoded = [] #Numbers representing encoded characters
keys = [] #Key numbers to unlonk code
fakes = [] #Which items in "encoded" are fake
#All of these are stored in a file

if giveUserKey:
userkey = random.randrange(2 ** 10,  2 ** 16)
# Key given to the user, entered during decryption for confirmation
# Could change range for greater security


Why isn't the key a parameter?

    else:
userkey = 1

for char in string:
ordChar = ord(char)
key = random.randrange(sys.maxsize)
encoded.append(hex((ordChar + key) * userkey))
keys.append(hex(key))


These just aren't keys. Don't call them that.

        if random.randrange(fakeRate) == 0:
fake = hex(random.randrange(sys.maxsize) * userkey)
encoded.append(fake)
fakes.append(fake)

if doubleEncode:
encoded = [string.encode() for string in encoded]
keys = [string.encode() for string in keys]
fakes = [string.encode() for string in fakes]


Since these are all hex strings, why in the world are you encoding them?

    hashValue = hex(hash("".join([str(obj) for obj in encoded + keys + fakes]))).encode()

return encoded, keys, hashValue, fakes, userkey

def decode(encoded, keys, hashValue, fakes, userkey = 1):
if hash("".join([str(obj) for obj in encoded + keys + fakes])) != eval(hashValue):
#File has been tampered with, possibly attempted reverse-engineering
return "ERROR"


Do not report errors by return value, use exceptions.

    for fake in fakes:
encoded.remove(fake)


What if coincidentally one of the fakes looks just like one of the data segments?

    decoded = ""

for i in range(len(keys)):


Use zip to iterate over lists in parallel

        j = eval(encoded[i]) / userkey


Using eval is considered a bad idea. It'll execute any python code passed to it and that could be dangerous.

        decoded += chr(int(j - eval(keys[i])))


It's better to append strings into a list and join them.

    return decoded