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中的整个文本,将消息中的每个字母转换为其选择的对应项。

除了我收到的错误之外,这段代码看起来非常繁琐和低效。

是否有更快的方法来达到这个结果?

c#将字符串中的所有字母切换为不同的预选字母

为了完整,我还将包括信息,您正在做的称为凯撒密码

你可以自己定义一个合适的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";