Шифрование текста по ключевому слову - C#
Формулировка задачи:
Привет всем! Копался в поисках алгоритмов шифрования на C# и наткнулся на данный код (ниже). Не могу разобраться в том, как зависит зашифрованный текст от ключевого слова. Мог бы кто-нибудь из добродушных помочь понять алгоритм шифровки (как кол-во буковок и сами буковки влияют на конечный результат??) в коде немного путаюсь, когда начинаю сам разбирать.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
CryptWord crypt = new CryptWord("WORLD");
string crypted = crypt.Encrypt("MY BIG IDEA IS WRITE THIS");
// получаем: IY OEB ELDW EQ VPESD SCEQ
string decrypted = crypt.Decrypt(crypted);
// получаем: MY BIG IDEA IS WRITE THIS
try
{
crypt.Encrypt("My big idea is write this");
}
catch (CryptException ex)
{
/*
* Требуется расширение алфавита, так как C# рассматривает 'Y' != 'y'
*
* ex.Message = "Строка переданная для шифрования/дешифрования содержит символ 'y' отсутствующий в алфавите"
*/
}
crypt = new CryptWord("WORMS"); // было WORLD
crypted = crypt.Encrypt("MY BIG IDEA IS WRITE THIS");
// получаем: HY ODB DMSW DP VNDQS QCDP
decrypted = crypt.Decrypt(crypted);
// получаем: MY BIG IDEA IS WRITE THIS
}
}
class CryptWord
{
public CryptWord(string word)
{
cryptAlph = new char[alph.Length];
int len = word.Length; int alphLen = alph.Length;
if (len > alphLen) throw new CryptException("Кодовое слово не может быть длинее алфавита");
for (int i = 0; i < len; i++)
{
char w = word[i];
for (int j = 0; j < i; j++)
{
if (cryptAlph[j] == w) throw new CryptException("Кодовое слово не может содержать повторяющиеся буквы");
}
cryptAlph[i] = w;
}
int idx=len;
for (int i = 0; i < alphLen; i++)
{
bool skip = false;
for (int j = 0; j < len; j++)
{
if (alph[i] == word[j])
{
skip = true; break;
}
}
if (!skip) cryptAlph[idx++] = alph[i];
}
}
/// <summary>
/// Алфавит
/// </summary>
static readonly char[] alph = "ABCDEFGHIJKLMNOPQRSTUVWXYZ ".ToCharArray();
/// <summary>
/// Шифрованный алфавит
/// </summary>
char[] cryptAlph;
/// <summary>
/// Зашифровать строку
/// </summary>
/// <param name="input">Строка для шифрования</param>
/// <returns>Шифр</returns>
public string Encrypt(string input)
{
return transfer(input, alph, cryptAlph);
}
/// <summary>
/// Расшифровать строку
/// </summary>
/// <param name="cryptedStr">Шифр</param>
/// <returns>Дешифрованная строка</returns>
public string Decrypt(string cryptedStr)
{
return transfer(cryptedStr, cryptAlph, alph);
}
string transfer(string input, char[] from, char[] to)
{
StringBuilder ret = new StringBuilder(input.Length);
int len = input.Length; int fromLen = from.Length;
for (int i = 0; i < len; i++)
{
int idx = -1; char w = input[i];
for (int j = 0; j < fromLen; j++)
{
if (from[j] == w) { idx = j; break; }
}
if (idx == -1) throw new CryptException("Строка переданная для шифрования/дешифрования содержит символ '" + w + "' отсутствующий в алфавите");
ret.Append(to[idx]);
}
return ret.ToString();
}
}
class CryptException : Exception
{
public CryptException(string message)
: base(message)
{
}
}
}Решение задачи: «Шифрование текста по ключевому слову»
textual
Листинг программы
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace RC4Test
{
public partial class Form1 : Form
{
byte[] S = new byte[256];
int x = 0;
int y = 0;
public Form1(byte[] key)
{
init(key);
}
public Form1()
{
InitializeComponent();
}
private void init(byte[] key)
{
int keyLength = key.Length;
for (int i = 0; i < 256; i++)
{
S[i] = (byte)i;
}
int j = 0;
for (int i = 0; i < 256; i++)
{
j = (j + S[i] + key[i % keyLength]) % 256;
S.Swap(i, j);
}
}
public byte[] Encode(byte[] dataB, int size)
{
byte[] data = dataB.Take(size).ToArray();
byte[] cipher = new byte[data.Length];
for (int m = 0; m < data.Length; m++)
{
cipher[m] = (byte)(data[m] ^ keyItem());
}
return cipher;
}
public byte[] Decode(byte[] dataB, int size)
{
return Encode(dataB, size);
}
private byte keyItem()
{
x = (x + 1) % 256;
y = (y + S[x]) % 256;
S.Swap(x, y);
return S[(S[x] + S[y]) % 256];
}
private void button1_Click(object sender, EventArgs e)
{
byte[] key = ASCIIEncoding.ASCII.GetBytes(textBox1.Text);
Form1 encoder = new Form1(key);
string testString = textBox3.Text;
byte[] testBytes = ASCIIEncoding.ASCII.GetBytes(testString);
byte[] result = encoder.Encode(testBytes, testBytes.Length);
string vix = System.Text.Encoding.UTF8.GetString(result);//в RC4
textBox2.Text = vix;
var sb = new StringBuilder();
foreach (var bt in Encoding.Unicode.GetBytes(vix))
}
}
static class SwapExt
{
public static void Swap<T>(this T[] array, int index1, int index2)
{
T temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
}
}