Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何为Caesar cipher同时替换多个字母?_C#_Encryption_Replace_Caesar Cipher - Fatal编程技术网

C# 如何为Caesar cipher同时替换多个字母?

C# 如何为Caesar cipher同时替换多个字母?,c#,encryption,replace,caesar-cipher,C#,Encryption,Replace,Caesar Cipher,我目前正在开发一个程序,该程序使用Caesar cipher对用户输入字符串进行加密,将特定字母替换为自定义预设字母。例如A=R、B=T、C=O等 当前计划: using System; class Program { static void Main(string[] args) { String decryptedInput = Console.ReadLine().ToUpper(); String encryptedOutput = dec

我目前正在开发一个程序,该程序使用Caesar cipher对用户输入字符串进行加密,将特定字母替换为自定义预设字母。例如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();
    }
}
我确实得到了输出,但是有一些加密错误。问题是,由于代码行彼此紧跟,已经转换的字母会再次转换

例如:字母A被加密/转换为R。当程序到达字母R时,该字母再次被加密/转换,最终为X,该字母在代码中稍后被转换为U。这几乎发生在每封信上,然后我得到一个加密的文本,我永远无法解密


有什么方法可以同时替换所有字母,还是建议我使用另一个函数?

这里是最简单的表示方法

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();
这是伪代码。但这非常简单,您可以理解需要构建新字符串,因为字符串是不可变的

我贴了这本词典,可以反向搜索。您可以使用列表

现在,当您加密/解密时,您可以更清楚了。
对于encrypt do list.Firstc=>c.Enc.equalInputChar和decrypt list.Firstc=>c.Dec.equalInputChar,这里是最简单的表示方法

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();
这是伪代码。但这非常简单,您可以理解需要构建新字符串,因为字符串是不可变的

我贴了这本词典,可以反向搜索。您可以使用列表

现在,当您加密/解密时,您可以更清楚了。
对于encrypt do list.Firstc=>c.Enc.equalInputChar和decrypt list.Firstc=>c.Dec.equalInputChar,我将从外部帮助您,了解它的工作原理是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,我将在外部帮助您,了解它的工作原理是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

如果您想继续使用已实施的简单替换策略,而不是执行@T.S.演示的字典模糊处理,您可以执行以下操作,您的地图有3个不同的组需要此处理,因此使用空格

按连接对地图进行排序 通过将一个循环映射到外部值来中断任何循环 向后处理地图 将步骤2设置为正确的值 代码:


如果您想继续使用已实施的简单替换策略,而不是执行@T.S.演示的字典模糊处理,您可以执行以下操作,您的地图有3个不同的组需要这种处理,因此使用空格

按连接对地图进行排序 通过将一个循环映射到外部值来中断任何循环 向后处理地图 将步骤2设置为正确的值 代码:

我会用字典和linq来做这件事。请注意,字典中未包含的任何字符、数字、空格和符号都不会被转换。当我对字典进行查找时,请注意我是如何将输出字符设置为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);

    }
}
我会用字典和linq来做这件事。请注意,字典中未包含的任何字符、数字、空格和符号都不会被转换。当我对字典进行查找时,请注意我是如何将输出字符设置为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);

    }
}

就像其他人提到的,您一次替换了一些字符倍数。这可能不是期望的行为:

eg: A -> R -> 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());

就像其他人提到的,您一次替换了一些字符倍数。这可能不是期望的行为:

eg: A -> R -> 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());

这些字母之间是否有圆形映射?如果没有,那么您可以按照转换顺序绘制出所有字母,并按照向后的顺序进行替换。但看起来整个映射是一个圆。请使用StringBuilder.Replace,而不是String.Replace。它在StringBuilder的缓冲区中进行替换。Replace在每个操作上创建一个新字符串,因为字符串是不可变的。会给你更多版本的代码让你目不转睛…你在替换的两边都是P而不是W,这不好。在任何字母之间有循环映射吗?如果没有,那么您可以按照转换顺序绘制出所有字母,并向后进行替换
顺序但看起来整个映射是一个圆。请使用StringBuilder.Replace,而不是String.Replace。它在StringBuilder的缓冲区中进行替换。Replace在每个操作上创建一个新字符串,因为字符串是不可变的。将为您提供更多版本的代码供您查看…在替换的两侧都有P而不是W,这不好。不能使用char作为字符串对字符串字典的键。@Xiaoy312确定-这是伪代码。这是一种非常有效的方法,你只需遍历字符串一次,每次迭代只需支付字典查找的费用。不能使用char作为字符串到字符串字典的键。@Xiaoy312当然-这是伪代码。这是一种非常有效的方法,你只需要遍历字符串一次,每次迭代只需支付字典查找的费用。