我正在制作一个凯撒密码,目前我有一个 3 的类次,我想用它来加密消息。如果任何字母有“x、y 或 z”,它会给我一个越界数组错误(因为移位是 3)。
如何通过返回到数组的开头但以移位的剩余部分结束来传递错误?
这是我目前的代码:
using System;
using System.Text;
//caesar cipher
namespace Easy47
{
class Program
{
static void Main(string[] args)
{
const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var input = Input(alphabet);
Encrypt(3, input, alphabet);
Console.WriteLine();
}
private static void Encrypt(int shift, string input, string alphabet)
{
var message = new StringBuilder();
foreach (char letter in input)
{
for (int i = 0; i < alphabet.Length; i++)
{
if (letter == alphabet[i])
{
message.Append(alphabet[i + shift]);
}
}
}
Console.WriteLine("\n" + message);
}
private static string Input(string alphabet)
{
Console.Write("Input your string\n\n> ");
string input = Console.ReadLine().ToUpper();
return input;
}
}
}
最佳答案
您使用模运算符:
var i = 255
var z = i % 200 // z == 55
在这里你的情况:
for (int i = 0; i < alphabet.Length; i++)
{
if (letter == alphabet[i])
{
message.Append(alphabet[ (i + shift) % alphabet.Length]);
}
}
如果在添加 shift
之后索引大于 alphabet.Length
,它将再次从 0 开始。
无关,但你的循环不是很有效。 "ZZZZZ"
的消息将通过您的完整字母表进行 5 次翻译。您应该使用字典作为查找。您可以在开始翻译消息之前创建它,然后您的查找速度非常快 - 这就是字典的优势所在。 O(1) 查找 :o)
如果你稍微了解一下linq,这应该是可以理解的:
// needs: using System.Linq;
private static void Encrypt(int shift, string input, string alphabet)
{
var message = new StringBuilder();
// create a string that is shifted by shift characters
// skip: skips n characters, take: takes n characters
// string.Join reassables the string from the enumerable of chars
var moved = string.Join("",alphabet.Skip(shift))+string.Join("",alphabet.Take(shift));
// the select iterates through your alphabet, c is the character you currently handle,
// i is the index it is at inside of alphabet
// the rest is a fancy way of creating a dictionary for
// a->d
// b->e
// etc using alphabet and the shifted lookup-string we created above.
var lookup = alphabet
.Select( (c,i)=> new {Orig=c,Chiff=moved[i]})
.ToDictionary(k => k.Orig, v => v.Chiff);
foreach (char letter in input)
{
// if the letter is not inside your alphabet, you might want to add
// it "as-is" in a else-branch. (Numbers or dates or .-,?! f.e.)
if (lookup.ContainsKey(letter))
{
message.Append(lookup[letter]);
}
}
Console.WriteLine("\n" + message);
}
关于c# - 如何越界回到数组的开头?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49835075/