Реализации алгоритмов/RC4


CПравить

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];
}

C#Править

Пример реализации класса 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;
        }
    }
}