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

时间:2016-10-13 11:22:30

标签: c# string cryptography

在处理一个简单的项目时,我试图想出一个非常基本的加密系统,它允许我将消息中的字母切换到另一个预先选择的字母。到目前为止,我已经尝试了几种方法,但到目前为止我的尝试都没有成功。 (*注意:这不是为了学习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中的整个文本,将消息中的每个字母切换到其选定的对应字母。

除了我收到的错误,这段代码看起来非常麻烦且效率低下。

有更快的方法来实现这个结果吗?

4 个答案:

答案 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";