在处理一个简单的项目时,我试图想出一个非常基本的加密系统,它允许我将消息中的字母切换到另一个预先选择的字母。到目前为止,我已经尝试了几种方法,但到目前为止我的尝试都没有成功。 (*注意:这不是为了学习c#的基础知识以外的其他任何东西,所以在这种情况下,随机性和安全性并不重要,我只是想把一个字母变成另一个字母,以便学习如何去做)
所以首先我开始定义一些字符串,比如这个
string a = "a";
string b = "b";
string c = "d";
..... //continues to string z = "z"
接下来,我尝试根据输入到名为PlainTextBox
的文本框中的值创建一个新字符串,并将它们放在一个名为ChangedTextBox
的单独文本框中。此代码由按钮单击事件触发。
string str = PlainTextBox.Text;
char[] array = str.ToCharArray();
array[int.Parse(a)] = 'x';
array[int.Parse(b)] = 'y';
array[int.Parse(c)] = 'z';
.......// continues to (z)
str = new string(array);
ChangedTextBox.Text = str;
但是此代码抛出异常,因为输入不是有效整数。基本的想法是,如果用户键入" abc"在PlainTextBox
并按下按钮,ChangedTextBox
应显示" xyz"但是应该包含PlainTextBox中的整个文本,将消息中的每个字母切换到其选定的对应字母。
除了我收到的错误,这段代码看起来非常麻烦且效率低下。
有更快的方法来实现这个结果吗?
答案 0 :(得分:1)
为了完整起见,我还会包含一些信息,即您正在做的事情称为Caesar cipher
您可以为自己定义一个合适的Dictionary
var mapping = new Dictionary<char, char>()
{
{ 'a', 'x' },
{ 'b', 'y' },
{ 'c', 'z' }
// other letters
}
您可以在其中为每个原始字母分配应转换为的字母。然后你可以使用这个词典
ChangedTextBox.Text = new string(PlainTextBox.Text.Select(letter => mapping[letter].ToArray());
答案 1 :(得分:1)
您选择了错误的集合类型( array )进行映射; 词典更方便
private static Dictionary<char, char> m_Mapping = new Dictionary<char, char>() {
{'a', 'x'}, // a -> x
{'b', 'y'}, // b -> y
...
};
然后实现编码
// I'd rather used Linq
private static String Encode(String value) {
// Simplest: we don't check if the actual character can be mapped
return String.Concat(value.Select(c => m_Mapping[c]));
}
但是你的(修改过的)实施已经足够了:
private static String Encode(string str) {
char[] array = str.ToCharArray();
for (int i = 0; i < array.Length; ++i) {
// Simplest: we don't check if the actual character can be mapped
array[i] = m_Mapping[array[i]];
}
return new string(array);
}
最后,添加UI:
ChangedTextBox.Text = Encode(PlainTextBox.Text);
修改一般情况下,当m_Mapping
不包含某些字符的记录时(例如新行 \n
)因此我们希望保留这些完整字符,但我们无法使用直接m_Mapping[...]
,但应该实现EncodeChar
。
private static char EncodeChar(char value) {
char result;
if (m_Mapping.TryGetValue(value, out result))
return result;
else
return value;
}
并将EncodeChar(...)
代替m_Mapping[...]
private static String Encode(String value) {
return String.Concat(value.Select(EncodeChar(c)));
}
您的版本
private static String Encode(string str) {
char[] array = str.ToCharArray();
for (int i = 0; i < array.Length; ++i) {
array[i] = EncodeChar(array[i]);
return new string(array);
}
答案 2 :(得分:1)
正如其他答案所说,可能最好的解决方案是使用词典。但是,如果我理解你想要的东西,你只想用那个字母改变一个字母加上一个“圆形”方式的偏移。这个解决方案会做类似的事情(“abcd”作为输入它会返回“xyza”):
string input = "abcd";
char startChar = 'x';
char lastChar = 'z';
char firstChar = 'a';
byte[] asciiBytes=Encoding.ASCII.GetBytes(input);
byte[] encriptedByteArray = new byte[asciiBytes.Length];
int val = (int)startChar-(int)firstChar;
int i = 0;
foreach(byte b in asciiBytes)
{
var a=b + val;
if (a>(int)lastChar)
{
a = firstChar+(a-lastChar)-1;
}
encriptedByteArray[i] = (byte)a;
i++;
}
string encriptedArray = System.Text.Encoding.UTF8.GetString(encriptedByteArray);
使用此解决方案,您可以轻松更改offsety(更改startChar
)。它有改进的余地,例如它只适用于a-z的较低字母,可以更改为更广泛。
答案 3 :(得分:0)
int.Parse(a)
当然会抛出InvalidCastException,因为a是你定义的字符串
string a = "a";