1
votes

I am trying to create a substitution cipher using Visual Basic. I am new to programming and struggling so would appreciate some support please.

The cipher should do the following:

  1. Ask the user for a message to encrypt.
  2. Ask the user for a key (or ask the system to generate a key, whichever is easier to code).
  3. Encrypt the message using the key.
  4. Return encrypted message.

Example:

  • Message = hello
  • Alphabet: "abcdefghijklmnopqrstuvwxyz"
  • Key: "kxgtlmpqbwcnderfahjusviyoz"
  • Return encrypted message.

The main parts that I need help with are 2 and 3. What I need to know is the steps (English or syntax) to solve this and then I can try coding it myself. If you have an example that will be great.

Note that I am not seeking help on how to create a Caesar Cipher. A Substitution Cipher here will replace each letter with another character (which is the key).

Thanks.

3
Hard to help without knowing where you are. Useful concepts before you start would be arrays, dictionaries, loops, random, StringBuilder. Assuming your get a key from the user is a validation problem and not a UI one. If you don't understand the above yet, you need to take a step back and look them up. PS you do know that this sort of cipher can be cracked easily? - Tony Hopkinson

3 Answers

0
votes

I don't know any Visual Basic, so I can't give you code, but since you say that an explanation in English would be acceptable, let me try to break your steps into smaller ones that you may find easier to implement:

  1. First, you need to get the message from the user, for example by asking them to type (or copy & paste) in a string. I assume you know how to do that in VB, since I don't.

  2. Next, do the same for the key. (You probably should structure your program so that, if the key turns out to be invalid — which can be conveniently checked in the next step — you can loop back to this step and ask for a new key.) You may want to immediately convert the key to all lower case (or all upper case) and check that it has exactly 26 characters.

  3. Next, you should transform the key string into a map of which letters to replace with which. (This might not be necessary: some languages provide ready-made string transliteration functions, like PHP's strtr, which can use such a key string directly, but I assume you want to do this "from the ground up".) This can be a bit involved, so I'll break this into smaller steps:

    • First, you need to create the map object. VB hopefully provides some way of representing a map from characters to characters (or from single-letter strings to single-letter strings), maybe something called a "dictionary" or a "hash table".

    • Next, you need to loop over the characters of the key string. There are typically two ways to do that: either split the key string into a list of characters (or single-letter substrings) and loop over that, or just loop with an index i running from 1 to the length of the string and extract the i-th character from the string on each iteration. In either case, you also need to keep track (or calculate) the i-th letter of the alphabet, too.

    • Now, let's say you now have two variables: k containing the i-th letter in the key string, and a containing the i-th letter in the alphabet. Now, just insert an entry mapping k to a into your dictionary / hashtable / whatever it's called in VB. If your input message can contain both upper- and lowercase letters, you should insert a map entry for both the upper- and lowercase versions of k and a. Also, for decryption, just swap k and a so that the dictionary maps from a to k instead.

      • This is also a good time to check for the validity of the key: before inserting a map entry from k to a, check that there isn't already a map entry from k to some other letter. If there is, abort, let the user know the key was invalid and ask for a new key. This will ensure that the key has no duplicate letters, which (together with the fact that it's 26 letters long) ensures that it's a valid permutation of the alphabet. Oh, and you obviously should also check that k actually is a letter, and not, say, a punctuation character.

      • (For decoding, this is a bit trickier; you may want to build two maps, one in each direction, just so you can use the k-to-a map for validity checking.)

  4. Finally, you can use the map you built to encode the message: just loop over each character in the message, check whether it's found in the map, and, if so, replace it with the character it's mapped to. (If you can't modify the original message string, you can append each output character to a list of characters, and then finally join them all into a string. Or just start with an empty output string and append each output character to it directly, although that could be less efficient, depending on how string operations are implemented in VB, than building a list first.)

0
votes

Assuming the key your alphabet are the same length, You could do a FOR loop that check each character of your string (how that character is related to your key).

For example, your message "hello".

This isn't actual code, but just to demonstrate the concept on what you're asking:

for each letter in message
    position_in_alphabet = current_letter
    cipher_letter = key(position_in_alphabet)
    append cipher_letter to cipher_message

For example, "hello" is 5 characters. So this loop will loop 5 times. And the position in the alphabets are (8th, 5th, 12th, 12th, 15th). You plug those in relation to the key, and you get "qlnnr" (or however the key dictates).

Putting it all together, it'd look like:

Dim _message As String = "hello"
Const _plain As String = "abcdefghijklmnopqrstuvwxyz"
Const _key As String = "kxgtlmpqbwcnderfahjusviyoz"
Dim charPos As Integer = 0
Dim Cipher As String = ""

For i = 0 To _message.Length - 1
    charPos = _plain.IndexOf(_message(i))
    Cipher = Cipher & _key(charPos)
Next i

In reverse, look up the position of the cipher in relation to the key, then put that into the plaintext dictionary, like so:

Dim _cipher As String = "qlnnr"
Const _plain As String = "abcdefghijklmnopqrstuvwxyz"
Const _key As String = "kxgtlmpqbwcnderfahjusviyoz"
Dim charPos As Integer = 0
Dim Message As String = ""

For i = 0 To _message.Length - 1
    charPos = _key.IndexOf(_cipher(i))
    Message = Message & _plain(charPos)
Next i