Как я могу заменить несколько букв одновременно для Цезаря шифра? - PullRequest
0 голосов
/ 19 декабря 2018

В настоящее время я работаю над программой, которая шифрует (используя шифр Цезаря) строку ввода пользователя, заменяя определенные буквы пользовательскими предустановленными буквами.Например, A = R, B = T, C = O и т. Д.

Текущая программа:

using System;
class Program
{
    static void Main(string[] args)
    {
        String decryptedInput = Console.ReadLine().ToUpper();
        String encryptedOutput = decryptedInput.Replace("A", "R")
                                        .Replace("B", "B")
                                        .Replace("C", "T")
                                        .Replace("D", "O")
                                        .Replace("E", "P")
                                        .Replace("F", "M")
                                        .Replace("G", "Z")
                                        .Replace("H", "S")
                                        .Replace("I", "J")
                                        .Replace("J", "K")
                                        .Replace("K", "I")
                                        .Replace("L", "Y")
                                        .Replace("M", "P")
                                        .Replace("N", "G")
                                        .Replace("O", "L")
                                        .Replace("P", "V")
                                        .Replace("Q", "C")
                                        .Replace("R", "X")
                                        .Replace("S", "N")
                                        .Replace("T", "E")
                                        .Replace("U", "H")
                                        .Replace("V", "F")
                                        .Replace("P", "A")
                                        .Replace("X", "U")
                                        .Replace("Y", "Q")
                                        .Replace("Z", "D");
        Console.WriteLine(encryptedOutput);
        Console.ReadKey();
    }
}

Я получаю вывод, но есть некоторые ошибки шифрования.Проблема заключается в том, что, поскольку строки кода располагаются друг за другом, уже преобразованные буквы преобразуются снова.

Например: буква «А» зашифрована / преобразована в «R».Когда программа получает букву «R», буква снова зашифровывается / преобразуется и в конечном итоге становится буквой «X», которая позже преобразуется в код «U».Это происходит почти с каждой буквой, и тогда я получаю зашифрованный текст, который я никогда не смогу расшифровать.

Есть ли способ заменить все буквы одновременно, или вы просто порекомендовали бы мне использоватьдругая функция?

Ответы [ 5 ]

0 голосов
/ 19 декабря 2018

Как и другие упоминали, вы заменили несколько символов времени.Это, вероятно, не желаемое поведение:

eg: A -> R -> X -> U

Кроме того, кажется, что в этих строках есть опечатка:

.Replace("V", "F")
.Replace("P", "A")   // should this be W->A ?
.Replace("X", "U")

Все это может способствоватьВаша проблема.

Чтобы предотвратить это, просто сделайте один проход, чтобы заменить строку:

// build up character mappings for decryption
const string EncryptedLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string DecryptedLetters = "RBTOPMZSJKIYPGLVCXNEHFAUQD";
var decryptionMapping = EncryptedLetters.Zip(DecryptedLetters, Tuple.Create)
    .ToDictionary(x => x.Item1, x => x.Item2);

// decrypt the message
var encryptedMessage = "CTHC";
var decryptedMessage = encryptedMessage
    .Select(x => decryptionMapping[x])
    .Aggregate(new StringBuilder(), (sb, x) => sb.Append(x), sb => sb.ToString());
0 голосов
/ 19 декабря 2018

Я бы сделал это, используя Dictionary и linq.Обратите внимание, что любые символы (цифры, пробелы, символы), отсутствующие в словаре, не будут преобразованы.Когда я выполняю поиск по Dictionary, обратите внимание, как я устанавливаю вывод char в текущее значение char foreach.Кроме того, так как это чувствительно к регистру, я должен преобразовать строку в верхний регистр.

public class Program
{

    public static void Main(string[] args)
    {           

     string encryptedOutput = "";
        var decryptedInput = "this is a test string";
        Dictionary<char,char> cipherTable = 
        new Dictionary<char,char>{
            {'A', 'R'},
            {'B', 'B'},
            {'C', 'T'},
            {'D', 'O'},
            {'E', 'P'},
            {'F', 'M'},
            {'G', 'Z'},
            {'H', 'S'},
            {'I', 'J'},
            {'J', 'K'},
            {'K', 'I'},
            {'L', 'Y'},
            {'M', 'P'},
            {'N', 'G'},
            {'O', 'L'},
            {'P', 'V'},
            {'Q', 'C'},
            {'R', 'X'},
            {'S', 'N'},
            {'T', 'E'},
            {'U', 'H'},
            {'V', 'F'},
            {'W', 'A'},
            {'X', 'U'},
            {'Y', 'Q'},
            {'Z', 'D'}
        };         
        encryptedOutput = string.Join("",decryptedInput
                                        .ToUpper()
                                        .ToArray()
                                        .Select(c => {char outChar = c; cipherTable.TryGetValue(c, out outChar); return outChar;}));
        Console.WriteLine(encryptedOutput);

    }
}
0 голосов
/ 19 декабря 2018

Я помогу вам с внешним миром, выяснить, как это работает, - хорошее упражнение в Linq и остальной библиотеке.

static void Main(string[] args)
{    
    string decryptedInput = "Hello World!";
    string encryptedOutput = new string(decryptedInput.Select(EncryptChar).ToArray());
    Console.WriteLine(encryptedOutput);
}

private static char EncryptChar(char arg)
{
    return arg;
}

Теперь ваша проблема сводится к написанию лучшего EncryptChar ()

0 голосов
/ 19 декабря 2018

Если вы хотите придерживаться своей простой стратегии замены, которую вы реализовали, вместо того, чтобы запутывать словарь, который продемонстрировал @TS, вы можете сделать следующее, ваша карта имеет 3 различные группы, которые нуждаются в этом лечении, отсюда и пробел.

  1. Сортировка карты по соединениям
  2. Разрыв любых петель путем сопоставления одного с внешним значением
  3. Обработка вашей карты в обратном направлении
  4. Установите шаг 2 направильное значение

код:

var encryptedOutput = decryptedInput
    .Replace("A", "AA")
    .Replace("P", "A")
    .Replace("M", "P")
    .Replace("F", "M")
    .Replace("V", "F")
    .Replace("P", "V")
    .Replace("E", "P")
    .Replace("T", "E")
    .Replace("C", "T")
    .Replace("Q", "C")
    .Replace("Y", "Q")
    .Replace("L", "Y")
    .Replace("O", "L")
    .Replace("D", "O")
    .Replace("Z", "D")
    .Replace("G", "Z")
    .Replace("N", "G")
    .Replace("S", "N")
    .Replace("H", "S")
    .Replace("U", "H")
    .Replace("X", "U")
    .Replace("R", "X")
    .Replace("AA", "R")

    .Replace("B", "B")

    .Replace("I", "II")
    .Replace("K", "I")
    .Replace("J", "K")
    .Replace("II", "J");
0 голосов
/ 19 декабря 2018

Самое простое представление о том, что вы хотите сделать, здесь

var dict = new Dictionary<Char, Char>();
// load dictionary here

var original = "ABC";
var newOne = new StringBuilder();
foreach (var c in original)
    newOne.Append(dict[c]);

return newOne.ToString();

Это псевдокод.Но это достаточно просто для вас, чтобы понять, что вам нужно создать новую строку, потому что строки неизменны

Я отправил Dictionary<string, string> - поиск можно выполнить в обратном порядке.Вы можете использовать List<T>.

 class ED 
 {
     public Char Enc {get; set;}
     public Char Dec {get; set;}
 }
 var list = new List<ED>();

Теперь вы можете быть более понятным при шифровании / дешифровании.Для шифрования выполните list.First(c => c.Enc.Equals(inputChar)), а для дешифрования list.First(c => c.Dec.Equals(inputChar))

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...