简体   繁体   中英

Why can't I take a 10 digit number from a string and use it to find the corresponding key in a dictionary?

I'm screwing around with encryption and i have most of it working, except the last bit. I was planning to take the encoded text and split it into 10 digit chunks in a list. This is because i have created a dictionary where each letter is a 10 digit random number. I flipped the keys and values around to create the decode dictionary. Theory being i can take the 10 digit number from the string and use it to find the corresponding key and therefore the letter it corresponds to.

However my problem is that when i try this i get a key error, where i can see the exact same number that corresponds to the key in the dictionary. I know it's there but it isn't finding it in the dictionary. Any ideas?

I am a newbie to programming in python and just thought i'd try something with encryption as I've just done an encryption module. I know it wont be an actual cipher i'm doing it more for me. Help with the problem will be much appreciated.

import random
"""Encrypt a piece of text, as it stands only alphabet characters will be encrypted. Not punctuation yet."""

def populate_encryption_key ():
    """Generates a dictionary, keys are the alphabet values random numbers"""
    dictionary = {'a': letter_number(101), 'b': letter_number(103), 'c': letter_number(107), 'd': letter_number(109), 'e': letter_number(113), 'f': letter_number(127), 'g': letter_number(131), 'h': letter_number(137), 'i': letter_number(139), 'j': letter_number(149), 'k': letter_number(151), 'l': letter_number(157), 'm': letter_number(163), 'n': letter_number(167), 'o': letter_number(173), 'p': letter_number(179), 'q': letter_number(181), 'r': letter_number(191), 's': letter_number(193), 't': letter_number(197), 'u': letter_number(199), 'v': letter_number(211), 'w': letter_number(223), 'x': letter_number(227), 'y': letter_number(229), 'z': letter_number(233), ' ': '0000000000'}
    return dictionary

def letter_number(number):
    """Generate a random number 10 digits long"""
    key = random.randint(number * 1000000, number * 10000000)
    while key % number != 0:
        key = key + 1
    else:
        if len(str(key))<10:
            key = key * 10
    return key

def code_string(text):
    """Turns each letter in the text to a number corresponding to the dictionary key"""
    code_string = ''
    for character in text:
        code_string = code_string + str(key[character])
    return code_string


def decode_string(text):
    """Splits the coded string into 10 digit long chunks to be able to find them in the reverse key dictionary"""
    a = [text[i:i+9] for i in range(0, len(text), 10)]
    return a

key = populate_encryption_key()
reverse_key = {key[value]: value for value in key}
encoded_string = code_string("how the bloody hell are you sir")
decoded_string = decode_string(encoded_string)

you should be able to take the 10 digit chunks from digit one and put them into reverse_key to find the letter it corresponds to.

There are two small, yet important, problems in your code, and they are easy to overlook. The first one, is that decode_string is chopping the encrypted text in chunks of 9 characters rather than 10, and that is easily fixed. The second problem that you might have is about looking up in the reverse_key using str rather than int . Now, I don't know if that is a problem for you or not, because the code you shared here doesn't actually do any decoding, so I have added it on my own.

I have commented the code below so it should be clear. I also preferred to add the key and reverse_key as parameters to the code_string and decode_string functions.

import random

"""Encrypt a piece of text, as it stands only alphabet characters will be encrypted. Not punctuation yet."""


def populate_encryption_key():
    """Generates a dictionary, keys are the alphabet values random numbers"""
    dictionary = {'a': letter_number(101), 'b': letter_number(103), 'c': letter_number(107), 'd': letter_number(109),
                  'e': letter_number(113), 'f': letter_number(127), 'g': letter_number(131), 'h': letter_number(137),
                  'i': letter_number(139), 'j': letter_number(149), 'k': letter_number(151), 'l': letter_number(157),
                  'm': letter_number(163), 'n': letter_number(167), 'o': letter_number(173), 'p': letter_number(179),
                  'q': letter_number(181), 'r': letter_number(191), 's': letter_number(193), 't': letter_number(197),
                  'u': letter_number(199), 'v': letter_number(211), 'w': letter_number(223), 'x': letter_number(227),
                  'y': letter_number(229), 'z': letter_number(233), ' ': '0000000000'}
    return dictionary


def letter_number(number):
    """Generate a random number 10 digits long"""
    key = random.randint(number * 1000000, number * 10000000)
    while key % number != 0:
        key = key + 1
    else:
        if len(str(key)) < 10:
            key = key * 10
    return key


def code_string(text, key):
    """Turns each letter in the text to a number corresponding to the dictionary key"""
    code_string = ''
    for character in text:
        code_string = code_string + str(key[character])
    return code_string


def decode_string(text, reverse_key):
    """Splits the coded string into 10 digit long chunks to be able to find them in the reverse key dictionary"""
    chuncked_text = [text[i:i + 10] for i in range(0, len(text), 10)]   # get 10 digits, not 9
    decoded_string = ''
    for chunk in chuncked_text:
        if chunk == '0000000000':  # the only string
            decoded_string += reverse_key[chunk]
        else:
            # all other keys are actually int, so convert them
            decoded_string += reverse_key[int(chunk)]
    return decoded_string

key = populate_encryption_key()
reverse_key = {key[value]: value for value in key}
encoded_string = code_string("how the bloody hell are you sir", key)
decoded_string = decode_string(encoded_string, reverse_key)

print(encoded_string)
print(decoded_string)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM