Реализации алгоритмов/RC4
(перенаправлено с «Программные реализации RC4»)
void rc4_init( unsigned const char* key, unsigned int key_length )
{
unsigned char temp;
for( i = 0; i != 256; ++i )
S[ i ] = i;
for( i = j = 0; i != 256; ++i )
{
j = ( j + key[ i % key_length ] + S[ i ] ) % 256;
temp = S[ i ];
S[ i ] = S[ j ];
S[ j ] = temp;
}
i = j = 0;
}
/* Вывод одного псевдослучайного байта */
unsigned char rc4_output()
{
unsigned char temp;
i = ( i + 1 ) % 256;
j = ( j + S[ i ] ) % 256;
temp = S[ j ];
S[ j ] = S[ i ];
S[ i ] = temp;
return S[ ( temp + S[ j ] )%256];
}
Пример реализации класса RC4:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace rc4 {
public class RC4 {
public byte[] text; //текст для шифрования/расшифрования
private byte[] S = new byte[256];
private int i = 0;
private int j = 0;
//просто для удобства обмена
private void swap(byte[] array, int ind1, int ind2) {
byte temp = array[ind1];
array[ind1] = array[ind2];
array[ind2] = temp;
}
//инициализация, алгоритм ключевого расписания
public void init(byte[] key) {
for (i = 0; i < 256; i++) {
S[i] = (byte)i;
}
j = 0;
for (i = 0; i < 256; i++) {
j = (j + S[i] + key[i % key.Length]) % 256;
swap(S, i, j);
}
i = j = 0;
}
//генератор псевдослучайной последовательности
public byte kword () {
i = (i + 1) % 256;
j = (j + S[i]) % 256;
swap(S, i, j);
byte K = S[(S[i] + S[j]) % 256];
return K;
}
//функция шифрования/расшифрования
public byte[] code() {
byte[] data = text.Take(text.Length).ToArray();
byte[] res = new byte[data.Length];
for (int i = 0; i < data.Length; i++) {
res[i] = (byte)(data[i] ^ kword());
}
return res;
}
//бинарная запись в файл
public void WriteByteArrayToFile (Byte[] buffer, string fileName) {
try {
FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
BinaryWriter bw = new BinaryWriter(fs);
for (int i = 0; i < buffer.Length; i++)
bw.Write(buffer[i]);
bw.Close();
fs.Close();
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
}
//бинарное чтение из файла
public Byte[] ReadByteArrayFromFile (string fileName) {
Byte[] buffer = null;
try {
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
long numBytes = new FileInfo(fileName).Length;
buffer = br.ReadBytes((int) numBytes);
br.Close();
fs.Close();
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
return buffer;
}
}
}
И пример использования вышеизложенного класса:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace rc4 {
class Program {
static void Main (string[] args) {
int key = 0;
Console.Write("Введите ключ: ");
string query = Console.ReadLine();
int.TryParse(query, out key);
byte[] bytekey = BitConverter.GetBytes(key);
Console.Write("Входной файл: ");
string infile = Console.ReadLine();
Console.Write("Результирующий файл: ");
string outfile = Console.ReadLine();
var ob = new RC4();
var test = new StatisticTests();
while (1 == 1) {
switch (menu()) {
case (1):
ob.text = ob.ReadByteArrayFromFile(infile);
ob.init(bytekey);
ob.WriteByteArrayToFile(ob.code(), outfile);
Console.WriteLine("Сообщение зашифровано!");
Console.Read();
break;
case (2):
ob.text = ob.ReadByteArrayFromFile(infile);
ob.init(bytekey);
ob.WriteByteArrayToFile(ob.code(), outfile);
Console.WriteLine("Сообщение расшифровано!");
Console.Read();
break;
case (3):
key = 0;
Console.Write("Введите ключ: ");
query = Console.ReadLine();
int.TryParse(query, out key);
bytekey = BitConverter.GetBytes(key);
Console.Write("Входной файл: ");
infile = Console.ReadLine();
Console.Write("Результирующий файл: ");
outfile = Console.ReadLine();
break;
case (4):
Environment.Exit(0);
break;
default:
Console.WriteLine("Такого действия нет!");
break;
}
}
}
private static int menu() {
Console.Clear();
Console.WriteLine("Выберите действие:");
Console.WriteLine(" 1. Шифровать");
Console.WriteLine(" 2. Дешифровать");
Console.WriteLine(" 3. Ввести новые данные");
Console.WriteLine(" 4. Выход");
Console.Write(" \n\n>>> ");
string action = Console.ReadLine();
int act = 0;
int.TryParse(action, out act);
Console.Clear();
return act;
}
}
}