c#将字符串中的所有字母切换为不同的预选字母
本文关键字:字符串 | 更新日期: 2023-09-27 18:13:04
在一个简单的项目上工作时,我试图想出一个非常基本的加密系统,它将允许我将消息中的字母切换到另一个预先选择的字母。到目前为止,我已经尝试了几种方法,但到目前为止,我的尝试都没有成功。(*注意:这不是为了学习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;
但是这段代码抛出一个异常,因为输入不是一个有效的整数。基本思想是,如果用户在PlainTextBox
中输入"abc"并按下按钮,ChangedTextBox
应显示"xyz",但应包括PlainTextBox中的整个文本,将消息中的每个字母转换为其选择的对应项。
除了我收到的错误之外,这段代码看起来非常繁琐和低效。
是否有更快的方法来达到这个结果?
为了完整,我还将包括信息,您正在做的称为凯撒密码
你可以自己定义一个合适的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());
您选择了错误的集合类型(数组)进行映射;字典更方便
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);
Edit:在一般情况下,当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);
}
可能最好的解决方案是使用字典,正如其他答案所说的那样。但如果我没理解错的话,你想要的是用一种"循环"的方式改变一个字母加上偏移量。这个解决方案会做类似这样的事情(输入"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);
使用此解决方案,您可以轻松更改偏移量(更改startChar
)。它有改进的空间,虽然,例如,它只适用于小写字母从a-z,它可以改变得更广泛。
int.Parse(a)
当然会抛出InvalidCastException因为a是你定义的字符串
string a = "a";