2

Beginner question Hi, I'm struggling to figure out a way to encrypt this message. Ideally my program should work like this:
1. Ask for input of a word/message to encrypt. This could include letters and spaces.
2. Generate a number between 2 and 20 (i'll call it x for now)
3. Then randomly select characters of length x to put between each letter of the inputted message.
4. Print said encrypted message.

Issue is when I run the code it prints the same random letter and also does not remove any spaces. It also only uses the same length each time I run the code. Any suggestions on why this happens? Thank you.

import random
chars = 'abcdeifghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'


def ranchar():
    y = random.randrange(2, 20)
    for x in range(2, y):
        ok = random.choice(chars)
        return ok

phrase = input('Please enter the message you would like to encrypt: ')
print(ranchar().join(phrase))

Output:

tQhQeQ QqQuQiQcQkQ QbQrQoQwQnQ QfQoQxQ QjQuQmQpQsQ QoQvQeQrQ QtQhQeQ QlQaQzQyQ QdQoQg

Process finished with exit code 0
  • You will need to create a seed for the random lib. There are different ways to do this, but you could make it dependent on the first or last letter of the input and then increment every time. Secondly you'll want to split it before it outputs so you can parse out the spaces. – Aaron Cloud Oct 31 '22 at 14:20
  • In order to filter spaces, have a look at [this question](https://stackoverflow.com/questions/8270092/remove-all-whitespace-in-a-string). – Reti43 Nov 01 '22 at 15:48
  • @Presumably `X` is the key for decryption. Not a strong system, but that is another topic. – Reti43 Nov 01 '22 at 15:49

2 Answers2

3

The main problem with your code is that you are not accumulating the random characters into a string or list. Instead, you are continually overwriting the random choice so that only the choice in the last pass through the loop is retained. The easiest fix is to eliminate the loop completely and use random.choices rather than random.choice.

Here is one solution (incorporating Reti43's helpful suggestion to use string.ascii_letters):

import random,string

chars = string.ascii_letters

def randstring():
    y = random.randrange(2, 20)
    return ''.join(random.choices(chars,k=y))

phrase = input('Please enter the message you would like to encrypt: ')

encrypted = randstring().join(phrase)
    
print(encrypted)

For example, one run of it with the phrase "hello world" produced

hlrTZhKdelrTZhKdllrTZhKdllrTZhKdolrTZhKd lrTZhKdwlrTZhKdolrTZhKdrlrTZhKdllrTZhKdd

Pedantic point: this isn't encryption at all so much as a simple form of steganography.

John Coleman
  • 51,337
  • 7
  • 54
  • 119
  • `chars` would be nicer with `from string import ascii_letters`. If my understanding is right, this produces the wrong output, as it always adds ONE random letter between the original the characters. Instead, it shoud generate `y` random letters every time. – Reti43 Oct 31 '22 at 16:19
  • @Reti43 I think that your understanding is correct. Thanks. Is your username after the chess player Richard Reti? – John Coleman Oct 31 '22 at 16:55
  • I think your previous approach in building the delimeters and letters in a list was correct. At the moment you generate said delimeter only once, which is also implied in the OP to be undesirable. You need to generate `y` once and then `random.choices(chars, y)` for each delimeter. And yes, it references the player, even though I have never played his opening. :) – Reti43 Nov 01 '22 at 15:45
  • @Reti43 Hard to know for sure. OP should clarify. I play the Reti sometimes but mostly as a transpositional pathway to a Queen's pawn game. – John Coleman Nov 01 '22 at 16:01
1

Here is my solution:

import random
chars = 'abcdeifghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'


def ranchar(phrase):
    output = []
    for v in phrase:
        output.append(v)
        output.append(random.choice(chars))
    return output

phrase = input('Please enter the message you would like to encrypt: ')
print(''.join(ranchar(phrase)))

You only give the join() function one character, so it'll only combine the 'q' to the prase.

Here is my output:

Please enter the message you would like to encrypt: the quick brown fox jumps over the lazy dog
tZhLeb DqDuHiacqkC SbdrqoWwAnO BfpoWxi HjnuVmZpEsM DoDvmedrY KtihpeT GlkaFzlyV Zdpocgi
Ziv Wu
  • 36
  • 3
  • Your method only adds a single character between letters. You need to generate the length with `x = random.randrange(2, 20)` at the top of your `ranchar` function and then use `random.choices(chars, x)`. – Reti43 Nov 01 '22 at 15:52