C# 如何为Caesar cipher同时替换多个字母?
我目前正在开发一个程序,该程序使用Caesar cipher对用户输入字符串进行加密,将特定字母替换为自定义预设字母。例如A=R、B=T、C=O等 当前计划: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
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当然-这是伪代码。这是一种非常有效的方法,你只需要遍历字符串一次,每次迭代只需支付字典查找的费用。