private static int[] Shift =
{ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
private static int[] H =
{ 14, 17, 11, 24, 01, 05, 03, 28, 15, 06, 21, 10, 23, 19, 12, 04,
26, 08, 16, 07, 27, 20, 13, 02, 41, 52, 31, 37, 47, 55, 30, 40,
51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32};
private UInt64 key;
public DES(String key)
{
this.key = 0;
for (int j = 0; j < key.Length; j++)
{
this.key |= (UInt64)(key[j] & 0xFF) << (j * 8);
}
}
private UInt64 Relocate(UInt64 val, int[] moves)
{
UInt64 result = 0;
for (int i = 0; i < moves.Length; i++ )
{
result |= ((val >> (moves[i] - 1)) & 1ul) << i;
}
return result;
}
private UInt64 Key(UInt64 Key, int index)
{
UInt64 tmp = Relocate(Key, G);
UInt64 C = tmp & 0xFFFFFFF;
UInt64 D = (tmp >> 28) & 0xFFFFFFF;
for (int i = 0; i < index; i++ )
{
for (int j = 0; j < Shift[i]; j++)
{
C = (C >> 27) | (C << 1);
D = (D >> 27) | (D << 1);
}
}
return Relocate((C << 28) | D, H);
}
private UInt32 f(UInt32 value, UInt64 key)
{
UInt64 tmp = Relocate(value, E) ^ key;
UInt32 result = 0;
int[] h = {1,6};
int[] w = {2,3,4,5};
for (int i = 0; i < 8; i++ )
{
UInt64 oct = (tmp >> (i * 6)) & 0x3F;
result |= S[i, (int)Relocate(oct, h), (int)Relocate(oct, w)] << (i * 4);
}
return (UInt32)Relocate(result, P);
}
private UInt64 codeBlock(UInt64 value)
{
value = Relocate(value, IP);
UInt32 R = (UInt32)(value & 0xFFFFFFFF);
UInt32 L = (UInt32)((value >> 32) & 0xFFFFFFFF);
for (int i = 1; i <= 16; i++)
{
UInt32 oldL = L;
L = R;
R = oldL ^ f(R, Key(key, i));
}
return Relocate(((UInt64)L << 32) | R , IPrev);
}
private UInt64 decodeBlock(UInt64 value)
{
value = Relocate(value, IP);
UInt32 R = (UInt32)(value & 0xFFFFFFFF);
UInt32 L = (UInt32)((value >> 32) & 0xFFFFFFFF);
for (int i = 16; i > 0; i--)
{
UInt32 oldR = R;
R = L;
L = oldR ^ f(L, Key(key, i));
}
return Relocate(((UInt64)L << 32) | R, IPrev);
}
private UInt64[] messageSpliter(String message)
{
List<UInt64> result = new List<UInt64>();
for (int i = 0; i < message.Length; i += 8)
{
UInt64 block = 0;
for (int j = 0; j < 8 && (i + j) < message.Length; j++)
{
block |= (UInt64)(message[i + j] & 0xFF) << (j * 8);
}
result.Add(block);
}
return result.ToArray();
}
private String messageCollector(UInt64[] message)
{
StringBuilder result = new StringBuilder();
for (int i = 0; i < message.Length; i++)
{
for (int j = 0; j < 8; j++)
{
result.Append((char)((message[i] >> j * 8) & 0xFF));
}
}
return result.ToString();
}
public String Code(String message)
{
List<UInt64> codes = new List<UInt64>();
foreach (UInt64 block in messageSpliter(message))
{
codes.Add(codeBlock(block));
}
return messageCollector(codes.ToArray());
}
public String Decode(String message)
{
List<UInt64> codes = new List<UInt64>();
foreach (UInt64 block in messageSpliter(message))
{
codes.Add(decodeBlock(block));
}
return messageCollector(codes.ToArray());
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Cripto.CodeAlgorithm;
using Cripto.CriptoAnalyze;
namespace Cripto
{
class Program
{
static void Main(string[] args)
{
String c = null;
do
{
String key = null;
do
{
Console.Write("Введите ключ: ");
key = Console.ReadLine();
for (int i = key.Length; i % 8 != 0; i++) key += " ";
if (key.Length > 8) Console.WriteLine("Ключ должен быть меньше 8 символов.");
} while (key.Length > 8);
DES des = new DES(key);
CodeTest(des);
Console.WriteLine("Повторить? (Y/N)");
c = Console.ReadLine().ToUpper();
}
while (c.Equals("Y"));
}
static void CodeTest(Code code)
{
Console.WriteLine("Введите сообщение: ");
String message = Console.ReadLine();
Console.WriteLine("Зашифрование : ");
String coded = code.Code(message);
Console.WriteLine(coded);
Console.WriteLine("Расшифрование: ");
String decoded = code.Decode(coded);
Console.WriteLine(decoded);
}
}
Вывод: в ходе выполнения этой практической работы, я научился шифровать информацию с помощью блочного симметричного шифра DES.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.